直接看日志中$upstream_addr的实际分布比检查配置更有效,它真实记录每次请求最终转发的后端地址(取第一个),结合时间范围聚合可直观识别流量倾斜;若某节点请求数超均值2倍且持续,需排查nat网关导致的ip哈希塌陷、real_ip未正确配置或上游代理ip干扰等问题。

直接看访问日志中各后端的实际请求分布,比检查配置更有效。重点不是“有没有启用 ip_hash”,而是“实际转发是否真按 IP 哈希均匀落地”。
用日志快速定位倾斜节点
$upstream_addr 字段记录每次请求真实转发到的后端地址,配合时间范围做聚合统计,就能直观看出哪台机器承接了远超平均的流量。
- 统计最近10分钟各后端请求数(排除异常值):
awk '$4 > "['$(date -d '10 minutes ago' +[%d/%b/%Y:%H:%M)']" {print $NF}' access.log | grep -v '[-*]' | cut -d',' -f1 | sort | uniq -c | sort -nr - 若某 backend 出现次数是其他节点的 2 倍以上,且持续数分钟,基本可判定分配失衡
- 注意:$NF 可能含多个地址(如重试),建议用 cut -d',' -f1 提取首次转发目标
查客户端 IP 分布是否天然集中
ip_hash 的本质缺陷在于它只取 IP 前三段参与哈希(如 192.168.1.x → 192.168.1),一旦大量用户共用同一 NAT 网关或云 LB,就会全部哈希到同一后端。
- 检查日志中客户端 IP 前缀分布:
awk '{print substr($1,1,index($1,".")-1)}' access.log | sort | uniq -c | sort -nr | head -5 - 若高频出现 10.128、172.16、192.168 等内网段,且对应后端请求量明显偏高,就是典型 NAT 导致的哈希塌陷
- 确认是否上游有硬负载设备(如 F5、SLB),Nginx 收到的 $remote_addr 实际是这些设备的固定出口 IP
验证真实客户端 IP 是否被正确识别
如果 Nginx 前面还有代理层,$remote_addr 默认拿不到真实用户 IP,ip_hash 就会基于代理 IP 计算,必然失衡。
- 检查是否配置了 real_ip 相关指令:
set_real_ip_from 指定可信代理网段;
real_ip_header X-Forwarded-For;
real_ip_recursive on; - 临时加一条日志字段验证:
log_format debug '$remote_addr $http_x_forwarded_for — $upstream_addr'; - 对比 $remote_addr 和 $http_x_forwarded_for 是否一致——不一致说明没做 real_ip 解析,ip_hash 正在对代理 IP 做哈希
交叉验证 upstream 状态与连接行为
即使日志显示某后端请求数高,也要排除是否因连接未释放、keepalive 配置不合理导致“假高负载”。
- 开启 stub_status,访问 /nginx_status 查看 active connections 和 accepts/accepted ratio
- 在 upstream 块中加入 keepalive 32;,并在 location 中配 proxy_http_version 1.1; proxy_set_header Connection ''; 防止短连接放大延迟波动
- 若某后端连接数长期偏低但请求数高,说明连接复用不足,每个请求都新建连接,ip_hash 表面稳定实则加重单点压力











