加权轮询本身不导致热点,但权重与后端真实能力不匹配会引发表观热点;排查关键在于验证流量分发是否符合权重比例及高权重点自身是否过载或异常。

加权轮询本身不会“导致”热点,但权重配置与后端真实能力不匹配时,会把过多请求持续压向某台服务器,形成表观上的热点——排查关键不是改权重,而是验证“流量去了哪”和“它为什么扛不住”。
看 access log 里真实分发目标是否符合权重比例
别只数日志里出现的 IP 总次数,要排除重试干扰。Nginx 默认记录的是最终成功转发的地址(可能已是第二次尝试),容易误判。
- 在 log_format 中加入 $upstream_addr,再用脚本过滤掉含逗号的记录(如
"192.168.1.10:8080, 192.168.1.11:8080"表示重试),只统计单地址行 - 用短连接压测(
ab -n 1000 -c 50 -k false或wrk -d10s --connections 1),关闭健康检查(临时注释 max_fails/fail_timeout),避免节点被踢出轮询队列 - 统计结果若明显偏离 weight 比例(比如 weight=3 和 weight=1 的两台,实际请求比是 5:1 而非接近 3:1),说明权重没按预期生效,或有其他机制覆盖
查 upstream 配置是否被静默降级
拼写错误、指令冲突或隐式覆盖会让加权轮询退化为简单轮询甚至 IP 哈希,表面看是“不均”,实则是策略失效。
- 运行
nginx -T 2>/dev/null | grep -A1 -B1 "server.*:",确认每行 server 后面真有 weight= 且值正确;常见错写如weigth=3、max_conn=100(少 s)会被忽略 - 检查 upstream 块外有没有
ip_hash、hash $remote_addr等指令——只要存在,weight 就完全不参与调度 - 确认 proxy_pass 引用的 upstream 名字拼写一致,比如配置了
upstream backend { ... },但 location 里写了proxy_pass http://backends/;,Nginx 会当域名解析失败,fallback 到第一个 server
盯住高权重节点自身的状态
如果 502 或超时集中在某台高权重点,大概率不是权重错了,而是它已经过载或响应异常,权重只是放大了问题。
- 登录该节点,用
ss -s | grep "inuse"和netstat -an | grep :8080 | wc -l查连接数,对比其他节点是否高出一倍以上 - 执行
netstat -s | grep "listen overflows",数值持续增长说明 accept queue 溢出,内核已丢包 - curl 直连它的健康接口:
curl -v http://192.168.1.20:8080/health 2>&1 | grep '^,若响应头大小远超其他节点(如 >4KB),而 Nginx 未调大 <strong>proxy_buffer_size</strong>,就会在这台触发 502
验证所有节点行为是否真正一致
加权轮询假设后端服务行为相同。一旦某台返回非法 header、超大 Cookie、慢响应或偶发 EOF,Nginx 可能反复重试它或提前终止连接,造成日志里“它被选中得多”的假象。
- 逐个直连各节点,用
curl -o /dev/null -s -w "%{http_code} %{time_total}\n" http://ip:port/测 HTTP 状态码和耗时,重点关注是否某台偶发 000 或超长延迟 - 检查各节点是否运行相同版本代码、相同 JVM 参数、相同中间件配置;旧机器是否开了调试日志、多启了监控 agent、或用了不同 TLS 握手策略
- 确认所有 server 行的健康检查参数一致:不能有的写
max_fails=2 fail_timeout=30s,有的完全没写,否则后者故障时不摘除,持续收流量











