ip_hash在局域网多用户共用出口ip时会导致负载严重倾斜,因其仅基于$remote_addr哈希且ipv4只取前三段,使所有用户被映射到同一后端;应通过real_ip_module还原真实ip或改用cookie/token等业务标识哈希,并外置session存储。

ip_hash 在局域网内多用户共用出口 IP 时,会把所有用户当成同一个客户端处理——这不是 bug,而是它的设计逻辑。它只看 $remote_addr,而 NAT 或代理之后,这个值就是出口网关的 IP(比如 203.101.5.8),所有请求哈希结果一致,全部落到同一台后端服务器。
为什么局域网下 ip_hash 会严重倾斜
ip_hash 对 IPv4 地址只取前 3 段参与哈希计算(如 192.168.1.x → 统一按 192.168.1.0 处理)。企业、校园或运营商网络中,成百上千终端共享一个出口 IP,导致:
- 所有请求固定打向 upstream 中某一台 server,其余节点长期空闲
- 单台后端 CPU、内存、连接数迅速拉满,响应延迟飙升甚至超时
- 登录态、购物车等依赖本地 Session 的功能,在不同用户间相互覆盖
还原真实 IP 是最直接的缓解手段
如果局域网出口设备(如防火墙、网关)支持透传原始客户端 IP(例如通过 X-Forwarded-For 或自定义头),可在 Nginx 中启用 real_ip_module 还原:
- 在
http块中配置set_real_ip_from 192.168.10.0/24(填你可信的内网网段) - 设置
real_ip_header X-Forwarded-For,并开启real_ip_recursive on防止中间层污染 - 确保
upstream仍用ip_hash,此时哈希依据已变为还原后的内网地址(如 172.16.5.123)
⚠️ 注意:该方法依赖上游设备真实、可信地携带原始 IP,若路径中存在不可控代理或头可伪造,反而带来安全风险。
更可靠的替代方案:换锚点,不依赖 IP
当 IP 不再具备用户唯一性,就该放弃基于 IP 的绑定逻辑,转向业务级标识:
-
hash $cookie_session_id;:适用于已有稳定 session cookie 的 Web 应用 -
hash $arg_token;或hash $http_authorization;:对接口类服务更友好,JWT 或 Bearer Token 天然唯一 -
hash $binary_remote_addr consistent;:需 Nginx 1.11.5+,一致性哈希在增减后端时影响更小
这些方式不受 NAT、DHCP 变更、移动网络切换影响,稳定性远高于 ip_hash。
必须同步补足 Session 共享能力
无论用哪种哈希策略,“请求钉住” ≠ “状态可用”。一旦目标服务器重启或宕机,用户会话就会丢失。因此:
- 必须将 Session 存储外置,如 Redis 或数据库
- 避免依赖后端内存存储,否则负载再均衡也无意义
- 配合健康检查与自动剔除机制,确保故障节点流量及时转移
ip_hash 本身不解决冲突,只是暴露了网络结构的现实。选对锚点 + 做好状态共享,才是局域网高并发下的稳态基础。











