ip hash 在长连接中仅首次请求哈希路由,后续复用同一后端;需配合真实ip还原、http/1.1、超时调优及头透传才能保障稳定黏滞。

不会重复计算。IP Hash 是在请求进入 upstream 路由阶段时,对客户端 IP 做一次哈希运算并取模,结果决定该请求转发到哪台后端——这个决策发生在连接建立前,且对整个长连接生命周期有效。
长连接下 IP Hash 只触发一次路由决策
当客户端复用 TCP 连接发送多个 HTTP 请求(如 HTTP/1.1 keep-alive 或 WebSocket),Nginx 不会对每个新请求重新执行 ip_hash 计算。只要底层 TCP 连接未断开,后续请求沿用首次建立连接时确定的后端节点。
- 首次请求到达时,Nginx 读取 $remote_addr(已还原为真实 IP),计算 hash 值,再对当前存活 server 数量取模,锁定目标 server
- 后续同连接内的请求直接复用该路由结果,不重新哈希、不查表、不判断
- 即使中间某台 server 被标记为 down,只要原连接仍活跃,已建立的长连接不会被中断或重路由
但连接复用本身可能被干扰
IP Hash 保证路由固定,却不保证连接能真正复用。若配置不当,长连接仍可能频繁重建,造成“看似跳转”的假象:
- proxy_http_version 未设为 1.1 或 1.2:HTTP/1.0 默认不支持 keep-alive,每次请求都新建连接
- 缺少 Connection 升级头透传:WebSocket 等协议需 proxy_set_header Upgrade $http_upgrade 和 Connection $connection_upgrade
- proxy_read_timeout / proxy_send_timeout 设置过短:空闲连接被 Nginx 主动关闭,下次请求被迫新建连接并重新哈希
- upstream 中混用 ip_hash 和 keepalive:Nginx 仍只维护一个共享连接池,不同后端的空闲连接混在一起,复用效率下降
真实 IP 还原失效会导致“伪重复哈希”
如果请求经过 CDN 或 NAT,$remote_addr 是代理 IP,大量用户被哈希到同一后端。此时看似“同一个 IP 总打同一台”,实则是无数用户被错误归并——表面稳定,实则严重倾斜。这种情况下,不是哈希重复,而是哈希输入失真。
- 必须配 set_real_ip_from + real_ip_header,把 X-Forwarded-For 最左有效 IP 覆盖 $remote_addr
- 验证方式:在后端日志打印 $remote_addr,确认其为用户真实公网 IP,而非 10.x.x.x 或 192.168.x.x
节点变更会强制重哈希,影响所有新连接
长连接本身不受影响,但新发起的连接(包括旧连接断开后的新建连接)会基于更新后的 upstream 列表重新哈希:
- 新增或删除 server 行 → 后端数量变化 → 取模基数变 → 所有新请求映射关系整体偏移
- 仅标记 server down → 剩余节点数减少 → 部分 IP 的取模结果改变 → 对应新连接会跳转
- 调整 server 行顺序(哪怕只是换行或加注释)→ Nginx 视为配置变更 → 触发全量重哈希











