排查nginx轮询分发不均,关键是验证真实流量分布而非仅看请求顺序,需检查是否被ip_hash等指令覆盖、节点是否健康在线、keepalive复用导致连接倾斜、后端响应异常引发隐性跳过。

排查 Nginx 轮询负载均衡分发不均,关键不是看“请求是否按顺序来”,而是确认实际流量是否落到各后端节点上——顺序只是调度逻辑,真实分布受连接复用、健康状态、配置覆盖等多重因素干扰。
检查是否被其他策略覆盖了轮询
轮询是默认算法,但极易被显式指令静默替代:
- 确认 upstream 块里没有 ip_hash、hash $remote_addr 或 sticky cookie 等会话保持指令,它们一旦存在,轮询完全失效
- 检查是否误启用了 least_conn 或 random,这些在配置中写一行就切换算法
- 用 nginx -T | grep -A 10 "upstream your_name" 输出生效配置,逐行核对有没有隐藏的 hash / least_conn 指令
验证后端节点是否全部在线且健康
看似轮询,实则部分节点已被 Nginx 主动剔除:
- 查看 error.log 中是否有 "upstream temporarily disabled" 或 "max_fails exceeded" 记录,说明某节点因失败次数超限进入 fail_timeout
- 执行 curl -s http://localhost/stub_status(需启用 stub_status 模块),观察 Active connections 和各 server 的当前状态;若某 server 显示 down 或 unavail,轮询自然跳过它
- 临时关闭健康检查验证:把所有 max_fails 改为 0,fail_timeout 注释掉,再压测观察分发是否恢复均匀
识别连接复用导致的“假均衡”
日志里请求数平均 ≠ 实际连接负载均衡,keepalive 会让多个请求挤在同一个 TCP 连接上:
- 在 backend 侧运行 ss -tnp | grep :8080 | awk '{print $5}' | sort | uniq -c | sort -nr,看 ESTAB 连接是否集中在少数 IP 上
- 对比 access log 中 $upstream_addr 的出现频次(请求维度)和 backend 上 netstat -an | grep ESTAB | wc -l(连接维度),若后者严重倾斜,就是 keepalive 复用问题
- 测试时加参数禁用复用:curl -H "Connection: close" http://your-domain/,或用 ab/wrk 加 -k 关闭 keepalive,再统计分发比例
排除后端响应异常引发的隐性跳过
某节点响应慢、超时或返回非法内容,Nginx 可能在轮询中途跳过它,却不报错:
- 检查 error.log 中是否密集出现 "upstream timed out"、"upstream prematurely closed connection" 或 "upstream sent too big header",这些都会触发重试并临时规避该节点
- 逐个直连后端做健康探活:curl -o /dev/null -s -w "%{http_code}\n" http://192.168.1.10:8080/health,确认所有节点响应时间与状态码一致
- 统一后端配置:确保各节点的 keepalive_timeout、max_header_size、thread pool 设置 无明显差异,避免某节点因配置弱而频繁拖慢或失败











