ip_hash 与 down 配合可实现零抖动平滑下线:标记节点为 down 后热重载,新请求自动避开该节点,ip_hash 哈希仅在可用节点间计算,已有连接不受影响,待连接自然衰减归零后再停服务。

在 Nginx 的负载均衡配置中,ip_hash 用于实现客户端 IP 的会话保持(即同一 IP 始终调度到同一后端节点),而 down 参数用于主动标记某个 upstream 节点为“不可用”。二者配合使用时,能实现在不中断已有连接的前提下,安全地下线某台后端服务器。关键在于:Nginx 不会将新请求分发给标记为 down 的节点,但已建立的长连接或复用连接不受影响;同时 ip_hash 的哈希逻辑会自动跳过 down 节点,确保哈希结果始终落在可用节点上。
ip_hash 的哈希行为与 down 的兼容性
ip_hash 并非简单对 IP 取模,而是基于 IP 的 IPv4 地址前 3 段(或 IPv6 的特定段)做哈希,再对当前 可用 节点数取余。当某个节点被设为 down,它会从可用节点列表中实时剔除,后续新请求的哈希计算只在剩余健康节点间进行,因此不会出现“哈希到 down 节点却无法转发”的问题。
- upstream 中即使有多个节点,只要一个被标
down,其余节点的哈希权重分布会自动重平衡 - 无需重启 Nginx 或重载配置,
down状态在 reload 后仍保留(需注意:仅限热重载生效,非 restart) - 已建立的连接(如 HTTP/1.1 keepalive、WebSocket)可继续处理完,不会被强制中断
下线操作四步走(零抖动)
以平滑下线 192.168.1.10:8080 为例:
-
第一步:在 upstream 块中标记节点为 down
修改配置,添加down关键字:upstream backend {<br> ip_hash;<br> server 192.168.1.10:8080 down;<br> server 192.168.1.11:8080;<br> server 192.168.1.12:8080;<br>} -
第二步:热重载配置
执行nginx -s reload,让变更生效。此时新请求不再路由至该节点 -
第三步:观察连接自然衰减
通过ss -tnp | grep :8080或 Nginx stub_status 查看该节点连接数是否持续下降;也可结合应用层日志确认无新会话创建 -
第四步:确认清零后停服务
待连接数归零(建议多等 1–2 个 keepalive_timeout 周期),再在后端服务器上停止服务或摘除机器
常见误区与避坑提示
实际操作中容易忽略以下细节:
-
ip_hash不支持weight参数,所以不能靠调低 weight 来“渐进下线”,down是唯一标准方式 - 若误删了
down标记又 reload,该节点会立即重新参与调度,已断开的客户端可能因 session 丢失报错 - 使用
max_fails/fail_timeout触发的被动下线,不等同于手动down—— 它可能反复上下线,不适合计划内维护 - 若 upstream 中只剩一个节点且被标
down,Nginx 会返回 502(因无可用节点),务必确保至少有一个 active 节点在线
验证与监控建议
下线过程中建议搭配以下手段验证效果:
- 用不同源 IP(如手机热点 + 笔记本)发起请求,检查响应头中的
X-Backend(需后端透出)是否始终避开目标节点 - 开启 Nginx 的
log_format记录$upstream_addr,观察 access log 中是否不再出现该节点地址 - 对关键业务接口做简易压测(如 100 并发 × 30 秒),确认成功率和响应时间无异常波动










