ip_hash 与 backup 不能协同工作,因其静态哈希机制强制同一IP固定映射某台server,故障时不重哈希也不切换至backup,仅持续尝试或报错;backup仅在全部非backup节点失效时启用,但ip_hash不触发该条件。

ip_hash 本身不支持直接搭配 backup 节点实现容灾,因为 ip_hash 的设计目标是会话保持——同一 IP 始终打到同一台后端,而 backup 节点只在所有非 backup 节点全部失效时才启用。一旦启用 ip_hash,Nginx 就不会把请求“切换”到 backup 节点去维持会话,否则会破坏 session 一致性。
为什么 ip_hash 和 backup 不能直接协同工作
ip_hash 是一种静态哈希策略:客户端 IP 经哈希后固定映射到某台 server。Nginx 不会在该 server 故障时重新哈希或改派 backup;它只会标记该 server 为不可用,并在后续对该 IP 的请求中持续尝试(直到恢复)或返回 502/503。backup 节点仅在 upstream 中所有非 backup 成员都 fail 时才参与调度,但 ip_hash 不会为此改变哈希结果,所以 backup 实际无法承接原 IP 的流量。
真正可行的容灾方案:ip_hash + 主动健康检查 + 共享 Session
要兼顾会话保持与故障自动接管,需绕过 ip_hash 对 backup 的限制,转而强化后端自愈能力:
- 保留 ip_hash 保证首次请求路由稳定,例如:
upstream backend {
ip_hash;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
} - 所有后端应用必须共享 Session 存储(如 Redis),避免用户因某台机器宕机而掉登录态
- 配置主动健康检查(需 nginx_upstream_check_module 或商业版 NGINX Plus),用 HTTP 探针定期验证 /health 端点,响应非 200 即刻隔离节点
- 在 proxy_pass 前设置合理超时:
proxy_connect_timeout 5s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout http_502 http_503; —— 这样当某台 server 响应超时或返回 502/503,Nginx 会尝试同一 upstream 内其他可用节点(注意:ip_hash 下仅限同哈希槽内节点;若该槽唯一且失效,则触发 next_upstream 失败,最终报错)
如果必须用 backup 节点兜底:放弃 ip_hash,改用 least_conn + 共享 Session
当业务允许短暂会话中断(或已通过 Redis/DB 全局共享状态),可换更容灾友好的策略:
- 用 least_conn 分配连接,天然支持故障转移:
upstream backend {
least_conn;
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 backup;
} - backup 节点会在前两台全不可用时立即接管全部流量
- 配合 Redis Session 和健康检查,用户感知不到服务中断
Nginx 层自身高可用:别只靠 upstream
真正防止单点故障,还得保障 Nginx 本体不挂:
- 部署两台 Nginx 服务器,用 Keepalived 绑定同一个 VIP,主备秒级切换
- 两台 Nginx 配置完全一致(含 upstream、health check、proxy 参数),并通过 rsync 或 GitOps 同步配置
- 避免在单台 Nginx 上做 backup 节点兜底,那只是后端容灾;VIP+Keepalived 才是 Nginx 层的容灾


















