ip_hash不支持backup因会破坏固定哈希映射,导致会话漂移;其仅允许静态上游列表,故障时通过健康检查自动跳过不可用节点维持映射稳定。

ip_hash 本身不支持备用节点(backup)、权重(weight)或 down 状态标记。一旦在 upstream 块中启用 ip_hash,Nginx 就会拒绝加载任何含 backup、weight、down 或 resolve 的 server 行——配置直接报错,无法启动。
为什么 ip_hash 和 backup 不能共存
ip_hash 的设计逻辑是“固定映射”:对客户端 IP 哈希后取模,结果严格对应 upstream 列表中的索引位置。如果允许 backup 节点,意味着列表长度和顺序在运行时可能动态变化(比如某台主节点 down 后 backup 晋升),哈希映射就会整体偏移,导致大量用户会话漂移——这违背了会话保持的初衷。
官方明确限定:ip_hash 只能用于至少两台“活跃”后端组成的静态列表,且顺序与数量必须稳定。所谓“高可用”,在 ip_hash 场景下,仅体现为:当某台 server 不可用时,Nginx 会临时跳过它,把原属于它的哈希请求重分配给剩余可用节点,但映射关系仍在剩余节点间维持(不是随机转发)。
实际可行的“故障转移”做法
- 用 health_check + ip_hash 组合:在 upstream 中开启主动健康检查(如 keepalive 或第三方模块),让 Nginx 自动剔除不可用节点;只要不增删或重排 server 行,ip_hash 映射在剩余节点上仍连续有效
- 手动维护“伪 backup”结构:例如部署 4 台节点,其中 3 台正常参与 ip_hash,第 4 台不写入 upstream,而是另配一个独立 upstream(不含 ip_hash)专用于应急切换;通过外部脚本或运维平台,在主集群异常时原子化切换 proxy_pass 目标
- 避免单点依赖,改用 cookie 粘性:真正需要 backup + 会话保持时,应放弃 ip_hash,改用 sticky cookie(需 nginx-plus 或开源 sticky-module),它天然支持 backup 和 weight,且不受 IP 变更影响
配置示例(健康检查版)
以下配置允许自动摘除故障节点,同时保持 ip_hash 映射稳定:
upstream backend {
ip_hash;
server 10.0.1.10:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.11:8080 max_fails=3 fail_timeout=30s;
server 10.0.1.12:8080 max_fails=3 fail_timeout=30s;
}
注意:
– 不要加 backup、weight、down;
– max_fails/fail_timeout 是唯一被 ip_hash 兼容的容错参数;
– 所有节点必须在同一网络段或具备一致延迟,否则哈希倾斜更明显。
更稳的替代路径
如果你的核心诉求是“会话不丢 + 故障自动接管”,ip_hash 并非最优解。推荐按优先级考虑:
- 后端统一 Session 存 Redis(如 Spring Session 或 PHP RedisSessionHandler),彻底解耦路由与状态
- 用 hash $cookie_session_id consistent; 替代 ip_hash,兼容代理、NAT 和扩缩容
- 升级到 Nginx Plus,使用内置 sticky cookie + backup 支持


















