ip_hash滚动升级时会话不平稳,因后端数量或顺序变化导致哈希槽重映射,引发约1/3用户会话漂移;IPv4仅取前三段哈希,且需real_ip_module处理代理IP。

测试 ip_hash 在滚动升级时的会话平稳性,核心是验证“同一客户端 IP 的请求是否始终被路由到同一台后端服务器”,尤其在有节点临时下线、权重变更或新实例加入时,会不会发生非预期的会话漂移。
准备可观察的测试环境
确保能清晰识别每次请求落到哪台后端:
- 每台后端服务返回唯一标识(如 HTTP 响应头
X-Backend-ID: server-a或响应体中包含主机名/IP) - Nginx 开启 access_log,并记录
$upstream_addr字段,直接看到转发目标 - 客户端使用固定真实 IP(避开 NAT/代理),或用
curl -H "X-Forwarded-For: 192.168.1.100"模拟稳定源 IP - upstream 配置启用
ip_hash,且暂不加weight或backup(它们与 ip_hash 不兼容)
模拟滚动升级过程并触发请求
按实际升级节奏逐步操作,每次操作后立即验证一致性:
- 先用同一 IP 连续发起 10+ 次请求(如
for i in {1..15}; do curl -s http://lb.example.com | grep X-Backend-ID; done),确认全部命中 server-1 - 执行“下线一台”:在 upstream 中注释或加
down标记某 server,重载 Nginx(nginx -s reload) - 立刻重复上述请求 —— 此时若出现部分请求跳转到新 server,说明发生了漂移;理想情况是仍全部落在剩余可用 server 中的同一台(因哈希槽重映射)
- 再上线原 server 或新增一台,再次 reload,观察是否又出现批量切换
重点检查漂移发生的边界条件
ip_hash 的稳定性天然受限于后端列表顺序和数量变化:
- 当后端从 3 台变为 2 台(如 server-c down),原有哈希结果整体偏移,约 1/3 用户会重新分配
- server 列表顺序改变(如把 server-b 提前),即使数量不变,也会导致大量用户漂移
- IPv4 地址只取前 3 段哈希(
192.168.1.100和192.168.1.101视为相同 IP),内网测试需注意该行为是否符合预期 - 如果前端有 CDN 或 WAF,
$remote_addr是代理 IP,必须配real_ip_module+X-Forwarded-For解析,否则所有用户被当成同一个 IP
对比验证更稳的替代方案
若发现漂移不可接受,可快速对比其他策略的实际表现:
- 改用
hash $cookie_JSESSIONID consistent;:用 Cookie 做一致性哈希,扩容缩容影响极小 - 关闭 ip_hash,启用
least_conn+ 后端接入 Redis 共享 Session:完全解耦路由与状态,升级零感知 - 用
sticky cookie(需编译模块):Nginx 自动下发路由 cookie,后端无需改造











