ip_hash本身不支持自动漂移,其“漂移”实为健康检查+down标记+哈希重计算协同实现的被动适应;需配置max_fails/fail_timeout、down手动下线、real_ip_module透传真实ip,并避免顺序调整与nat场景误用。

ip_hash 本身不支持自动漂移——它没有故障转移逻辑,也不会在后端节点宕机时“智能重映射”客户端 IP 到其他健康节点。所谓“自动漂移”,其实是通过 Nginx 的健康检查机制 + down 标记 + 哈希重计算协同实现的“被动适应”,而非主动漂移。
关键点在于:Nginx 的 ip_hash 在每次新请求路由时,只对当前 可用(即未被标记 down 且未触发 max_fails 屏蔽)的节点做哈希计算。只要节点被正确下线或失效,哈希空间自动收缩,原有 IP 请求自然落到剩余节点上,用户感知为“切换”,但底层是稳定、可预期的重新分配。
以下是真正可行、生产验证过的配置要点:
✅ 正确处理节点宕机的三步配置
-
启用基础健康探测
避免靠超时被动发现故障,应主动探测: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; }-
max_fails=3 fail_timeout=30s表示:30 秒内连续失败 3 次,该节点被临时屏蔽(状态变为unavailable),后续新请求不再分配给它。 - 屏蔽期间,
ip_hash自动跳过该节点,哈希仅在其余存活节点间进行,等效于“漂移”。
-
-
配合
down手动下线更可控
若需计划性维护(如升级、扩容),优先用down而非直接删配置:upstream backend { ip_hash; server 10.0.1.10:8080 down; # 主动下线,不参与任何哈希 server 10.0.1.11:8080; server 10.0.1.12:8080; }- 热重载(
nginx -s reload)后,新请求立即避开down节点。 - 已建立的长连接(HTTP keepalive / WebSocket)不受影响,自然结束。
-
ip_hash映射关系在剩余节点上保持一致,不会抖动。
- 热重载(
-
确保真实客户端 IP 可用,否则漂移无意义
如果$remote_addr是代理 IP(如 CDN、WAF、前置 Nginx),所有用户会被哈希到同一台后端,故障时全量“漂移”成单点失效:- 启用
real_ip_module,声明可信网段; -
proxy_set_header X-Real-IP $remote_addr;和X-Forwarded-For透传; - 日志中验证
$remote_addr是否为真实公网 IP。
- 启用
⚠️ 注意这些常见误区
-
ip_hash与weight、backup不兼容,加了就报错或失效; - 删除或调整
server行顺序会触发全量重散列,所有 IP 映射关系重排 → 大量会话中断,不是平滑漂移; - NAT/运营商共享 IP 场景下,几十人共用一个公网 IP,全部压到同一后端 → 故障时“漂移”实为雪崩式转移;
-
ip_hash不适用于 WebSocket 或长连接的保活,必须额外配proxy_read_timeout、proxy_send_timeout(建议 ≥ 300s)及Upgrade/Connection协议头透传。
不复杂但容易忽略。











