ip hash扩容必然导致全量漂移,应改用一致性哈希(hash $remote_addr consistent)或backup预占位方案,并同步做好真实ip还原、session外置和前端容错。

后端扩容一倍时,IP Hash 的映射关系会整体重排,大量用户请求被重新分配,导致登录态丢失、缓存失效、连接中断。这不是“震荡小不小”的问题,而是必然发生全量漂移——因为 IP Hash 本质是静态取模哈希,模数从 n 变成 2n,所有哈希值的余数几乎全部改变。
避免直接增删节点,用 backup 预占位
扩容前就在 upstream 中把新机器以 backup 状态写好,不参与流量分发:
- 原配置保持不变,ip_hash 正常运行,用户无感知
- 新增 server 行末尾加 backup,例如:
server 192.168.1.200:8080 backup; - 执行
nginx -s reload不影响现有映射,只是加载了“待命”节点
改用一致性哈希替代 ip_hash
这是最根本的解法。把 ip_hash; 替换为:
-
hash $remote_addr consistent;(IPv4/IPv6 均适用) - 扩容时仅约 1/n 的请求发生重定向(n 为原节点数),其余维持原路由
- 无需改业务、不依赖 IP 稳定性,天然支持动态伸缩
分阶段切换 + 权重过渡(仅限临时兼容)
若必须保留 ip_hash 且无法立刻改造架构,可人为控制漂移节奏:
- 先停用一半老节点(如标记为
down或注释掉),让剩余节点承载全量,观察稳定性 - 再启用新节点,此时 upstream 总数恢复为原规模(比如从 4 台 → 先减到 2 台 → 再加回 4 台),哈希模数不变
- 最后逐步放开全部节点,每次 reload 后监控
$upstream_addr日志,确认漂移比例可控
配套必须做好的三件事
单靠调整算法不够,需同步加固基础设施:
-
真实 IP 还原要准:确保
set_real_ip_from和real_ip_header X-Forwarded-For已生效,否则哈希对象错乱,漂移更剧烈 - 后端 session 外置:哪怕短期用 ip_hash,也应尽快将 session 存 Redis,解除对节点绑定的依赖
- 前端加容错逻辑:登录态丢失时自动触发 token 刷新或静默重登,用户无感











