ip_hash在NAT环境下会导致流量集中于单台后端服务器。因内网用户共用同一出口IP,哈希结果恒定,引发负载倾斜;应改用hash $realip_remote_addr consistent;或least_conn等更优策略。

当使用 ip_hash 作为 upstream 负载均衡策略时,Nginx 会将客户端 IP 的 IPv4 地址(或 IPv6 前 64 位)哈希后固定映射到某台后端服务器。但若大量内网请求经同一出口 NAT 设备(如防火墙、网关)转发,所有内网用户对外表现为**同一个公网出口 IP**,ip_hash 就会把全部流量打到后端集群中的**单台机器**,造成严重倾斜和单点压力。
确认是否真由 ip_hash 和出口 IP 集中导致
先验证问题根源,避免误判:
- 查 Nginx access 日志,用
awk '{print $1}' | sort | uniq -c | sort -nr | head -20统计来源 IP 分布——若前几名全是相同公网 IP(如 203.101.50.10),基本可锁定 NAT 出口集中 - 检查 upstream 配置中是否启用了
ip_hash,且未搭配hash $remote_addr consistent;等替代方案 - 观察后端各节点的请求量(如通过 Prometheus + nginx_exporter 或简单看连接数
ss -tn | grep :8080 | wc -l),确认是否某台明显过载
临时缓解:绕过出口 IP 做 hash
若业务允许且客户端能透传真实内网 IP(如通过 X-Forwarded-For),可改用更细粒度的 hash 变量:
- 确保前端网关(如 SLB、WAF)正确设置了
X-Forwarded-For,且 Nginx 已配置set_real_ip_from和real_ip_header X-Forwarded-For; - 在 upstream 中弃用
ip_hash,改用:hash $realip_remote_addr consistent;(需开启realip模块) - 若无法获取真实 IP,也可退而求其次用请求 URI 或 User-Agent 哈希(不推荐长期使用,但可快速分流):
hash $request_uri;
长期方案:替换为更健壮的负载策略
ip_hash 天然不适合 NAT 环境。推荐按场景选择:
-
需要会话保持但允许少量漂移:用
hash $cookie_session_id consistent;,配合应用写入 sticky cookie -
纯性能导向、无状态服务:直接用
least_conn或默认轮询(round_robin),它们不依赖客户端特征,天然规避出口 IP 问题 -
需强一致性与扩容友好:启用
hash $remote_addr consistent;(注意:这是标准 hash,非 ip_hash),支持后端增减时仅重映射部分 key,且不受出口 IP 影响
补充验证与监控建议
改完配置别急着上线,务必验证效果:
- 用多台不同内网机器(或模拟不同源 IP 的 curl)反复请求,观察后端日志中
$upstream_addr是否分散 - 在 Nginx 日志中加入
$remote_addr和$http_x_forwarded_for字段,便于后续分析实际来源 - 对 upstream 设置
max_fails=2 fail_timeout=30s,防止某台宕机后流量仍被 hash 固定过去


















