ip_hash 是 nginx 基于客户端 ip 哈希实现会话保持的机制,通过哈希 ipv4 前3段或 ipv6 地址并对可用后端数取模,固定路由请求;但依赖真实 ip 可还原、upstream 稳定且无 weight 等干扰参数,否则易导致会话漂移或负载倾斜,推荐改用 cookie 哈希或 redis 共享 session。

ip_hash 是 Nginx 中一种基于客户端 IP 哈希的会话保持机制,它把同一 IP 的请求固定分发到同一台后端服务器。但实际使用中常出现“看似所有用户都打到某一台机器上”的分配不均现象——这通常不是 bug,而是由 ip_hash 的设计原理和网络环境共同导致的。排查需从哈希逻辑、IP 真实性、后端数量变化三方面入手。
确认你看到的“不均”是否真实存在
ip_hash 的目标是稳定性,不是均匀性。它的哈希结果取决于:
– 客户端 IPv4 地址(取前 3 段做哈希)
– 后端 server 数量(哈希模运算基于当前 upstream 中 active server 总数)
– Nginx 版本(1.7.2+ 支持 IPv6,哈希逻辑略有不同)
这意味着:
- 大量用户来自同一局域网或 NAT 网关(如企业出口、校园网、运营商 CGNAT),它们的真实源 IP 被替换成同一个公网 IP,自然全部落到同一台后端
- 如果你用的是云服务,且前端有 SLB/WAF/CDN,Nginx 实际收到的是这些中间设备的 IP,而非用户真实 IP —— 此时 ip_hash 失效或误判
- 通过日志检查
$remote_addr是否真的是用户 IP:在 location 或 log_format 中加$remote_addr - $http_x_forwarded_for对比验证
检查 upstream 配置是否触发哈希重散列
ip_hash 要求 upstream 内不能配置 weight、max_fails、fail_timeout 等参数(否则会自动禁用 ip_hash)。更重要的是:当某台 server 被标记为 down(如健康检查失败),剩余 active server 数量减少,所有 IP 的哈希结果都会重新计算,引发大规模连接迁移。
排查方法:
- 执行
nginx -T | grep -A20 "upstream.*your_name",确认无 weight / backup / down 等干扰字段 - 查看 Nginx error log,搜索
ip_hash: server X is down或no live upstreams类提示 - 临时停掉健康检查(注释掉
check或health_check指令),观察分配是否趋于稳定
验证哈希分布是否理论不均(尤其 server 数非 2 的幂)
ip_hash 使用简单的 hash(ip) % n(n = 当前 active server 数)。当 n 不是 2 的幂时,小范围 IP 段容易集中映射到少数索引上。例如 3 台 server,哈希值对 3 取模后,余数为 0 的情况天然略多于 1 或 2(取决于哈希函数输出分布)。
你可以模拟验证:
- 写个简短脚本,取一批典型客户 IP(如 1000 个真实访问日志中的
$remote_addr),用相同哈希算法(Nginx 源码中为ngx_crc32_long())计算模 3 结果,统计各桶数量 - 对比 nginx stub_status 或第三方模块(如
nginx-module-vts)中各 upstream server 的 request 计数,看是否与模拟结果趋势一致 - 若确实偏差显著(如 3 台中一台承载 >60% 请求),可考虑改用
hash $remote_addr consistent;(一致性哈希,需 ngx_http_upstream_consistent_module)或升级到支持hash $binary_remote_addr consistent;的 OpenResty
替代方案建议:何时该放弃 ip_hash
ip_hash 适合简单场景,但脆弱性高。如果已确认是 NAT/IP 伪造或哈希倾斜导致问题,更健壮的做法是:
- 启用
real_ip模块还原真实 IP:set_real_ip_from 192.168.0.0/16;+real_ip_header X-Forwarded-For;(需确保上游可信) - 改用 cookie 会话保持:
sticky cookie srv_id expires=1h domain=.example.com path=/;(Tengine 或 commercial Nginx Plus 支持) - 业务层透传唯一标识(如登录态 token),用
hash $arg_uid或hash $http_x_user_id分发,完全绕过 IP 限制











