ip_hash支持down参数实现节点动态剔除:Nginx先过滤down节点生成可用列表,再对客户端IP哈希后对该列表长度取模,确保新请求仅分发至健康节点,原有连接不受影响。

直接在 upstream 的 server 行末尾加 down,配合 ip_hash 使用,Nginx 会自动从哈希计算中剔除该节点,新请求只在剩余可用节点间重新分布,已有连接不受影响——HASH 环逻辑上“收缩”,但不崩溃,也不漂移。
down 参数必须这样写才生效
语法严格,错一个字符就会导致 reload 失败:
- 必须写在 server 行末尾、分号之前:
server 192.168.1.10:8080 down; - 不能和 weight、max_fails、fail_timeout 等参数混用:
server 192.168.1.10:8080 weight=1 down;是非法的(ip_hash 本身就不支持 weight) - 不能换行或加空格分隔:
server 192.168.1.10:8080; down;会报配置错误 - ip_hash 启用时,backup 也不能与 down 共存于同一 server 行;如需备用接管,应另配独立 backup 节点
ip_hash 如何自动适配节点下线
它不是简单取模,而是基于当前**可用节点列表**动态计算:
- Nginx 初始化 upstream 时,先过滤掉所有带 down 的 server,形成精简后的可用节点数组
- 对客户端 IP 哈希后,只对这个精简数组长度取余,结果必然落在健康节点上
- 比如原 3 台节点:A、B、C,IP 哈希值为 2 → 分配到 C;当 C 标为 down 后,可用节点变为 A、B,哈希值 2 % 2 = 0 → 自动落到 A,不会“越界”或失败
- 原有长连接(keepalive、WebSocket)继续在 C 上处理完毕,新请求零流量进入,完全无抖动
下线操作四步闭环
整个过程不重启、不中断、可验证:
- 编辑 upstream 配置,在目标 server 行末尾追加
down; - 执行
nginx -t校验语法,通过后再nginx -s reload - 观察 access_log 或 stub_status,确认该节点请求数停止增长、活跃连接数逐步归零
- 维护完成,删掉 down 关键字,再次 reload 即恢复流量接入
容易踩的坑要避开
看似简单,但几个细节一错就失效:
- ip_hash 必须独占 upstream 块首行,不能缩进,也不能和 hash $cookie_xxx 等共存
- upstream 至少含 2 台非-down 节点,单节点 + ip_hash 会导致 Nginx 启动报错
- 如果用了 CDN 或代理,$remote_addr 可能是代理 IP,需配合
set_real_ip_from和real_ip_header还原真实客户端 IP,否则哈希失准 - down 状态不持久——Nginx 主进程重启后自动清除,所以不要依赖它做长期隔离


















