ip hash 本身不自动绕过故障节点,需显式配置 proxy_next_upstream 和 max_fails/fail_timeout 才能触发被动剔除;手动标记 down 或改用 consistent_hash 是更可靠的高可用方案。

IP Hash 模式本身不具备自动绕过故障节点的能力,一旦后端某台服务器宕机,原本被哈希到该节点的客户端请求会持续失败,直到 Nginx 主动将其标记为不可用——而这个过程依赖被动探测,响应滞后,容易造成用户长时间无法访问。
确认故障是否已触发 Nginx 的自动规避
Nginx 默认仅在连接失败(如 connect timeout、read timeout 或 5xx 响应)时,依据 proxy_next_upstream 配置尝试重试其他节点。但 ip_hash 是“绑定型”策略,重试行为受限:
- 必须显式配置 proxy_next_upstream error timeout http_500 http_502 http_503 http_504,否则即使后端挂了也不会切换
- 需配合 max_fails=1 fail_timeout=30s 等参数,让 Nginx 在单次失败后就将该 server 标记为 down(注意:ip_hash 下不支持 weight、backup 等动态参数,但 max_fails 和 fail_timeout 仍有效)
- 检查 upstream 中 server 是否已进入 “down” 状态:可通过 nginx -T 查看生效配置,或用 stub_status 模块观察 active connections 分布
临时缓解:手动标记故障节点
当发现某台后端不可用,又不能立即重启服务时,可快速在 upstream 块中添加 down 标识:
- 修改配置:
server 192.168.1.10:8080 down; - 执行 nginx -s reload,Nginx 会立即停止向该节点分发新请求(已有长连接不受影响)
- 该方式不破坏 ip_hash 的一致性,其余正常节点仍按原规则分流
长期方案:替换为更健壮的会话保持策略
ip_hash 天然不适合高可用场景。推荐两种替代路径:
-
改用 consistent hash + 真实用户标识:启用 real_ip_module 还原 $remote_addr,再配置
hash $realip_remote_addr consistent;,既保留会话粘性,又支持节点增删时的最小映射变动 -
基于业务字段哈希:如用户已登录,优先用
hash $cookie_sessionid consistent;;未登录则 fallback 到hash $http_x_forwarded_for consistent;,并配合 map 提取首层真实 IP,避免代理污染
配套加固:CDN 或中间层适配
若前端有 CDN、WAF 或 F5,$remote_addr 必然被覆盖,ip_hash 彻底失效:
- 在 nginx 中配置 set_real_ip_from 指定可信回源网段,并设 real_ip_header X-Forwarded-For
- 登录 CDN 控制台,确保开启“透传 X-Forwarded-For”,且未勾选“自动清洗”或“覆盖”选项
- 验证日志中 $remote_addr 与 $http_x_forwarded_for 是否分离:前者应为 CDN 节点 IP,后者应含真实用户 IP











