加权轮询未按预期分发流量,主因是隐性机制覆盖权重,需验证实际请求落点、排查拼写错误(如weigth)、确认无ip_hash等冲突策略、检查节点健康状态及响应性能。

加权轮询配置没按预期分发流量,问题通常不在“权重写错了”,而在于实际调度行为被其他机制覆盖、干扰或掩盖。重点不是看配置文件写了什么,而是验证请求真正落到哪台后端、为什么落不到、以及哪些隐性因素在起作用。
确认 upstream 中 weight 是否真实生效
拼写错误会让 Nginx 静默忽略关键参数:比如 weigth(少一个 t)、max_conn(少 s)、fail_time_out(下划线错位)等,都会导致 weight 不生效或健康检查失效,最终退化为默认轮询或单点转发。
- 运行
nginx -T 2>/dev/null | grep -A2 -B2 -i "weigth\|wight\|weights"快速扫出可疑拼写 - 检查所有
server行是否都显式声明了weight=;没写的默认是 1,容易误判为“未设权重” - 用
nginx -T输出完整生效配置,确认 upstream 块里没有重复定义、include 冲突或同名 upstream 覆盖
验证实际请求分发是否匹配权重比例
理论权重比(如 3:2:1)不等于实时日志中 $upstream_addr 的统计比——因为日志可能记录重试地址(第一次发给 B 超时,自动重试 A,日志记为 “B, A”),造成偏差。
- 在 log_format 中加入
$upstream_addr,用短连接压测(ab -n 1000 -c 100 -k false)并关闭健康检查,避免 failover 干扰 - 统计各 backend IP 出现频次:
awk '{print $12}' /var/log/nginx/access.log | sort | uniq -c | sort -nr - 对比理论占比(如 3:2:1 → 50%/33%/17%)与实测值,偏差超 ±10% 就需深挖
排查覆盖或削弱 weight 的隐性配置
只要以下任意一项存在,weight 就会完全失效或大幅失真:
- ip_hash、hash $cookie_jsessionid、hash $arg_id 等哈希策略启用时,加权轮询被彻底忽略
- 某节点因
max_fails=1频繁触发失败,进入fail_timeout状态,即使 weight=10 也收不到新请求 - 后端开启 keepalive 且客户端复用连接,大量请求挤在同一 TCP 连接上,全部落到同一台 server,但轮询日志看不出异常
- 用了
least_conn或random等非轮询算法,weight 参数本身就不参与计算
检查后端节点自身是否拖累调度效果
权重只是分配指令,不能弥补节点能力短板。高权重节点若响应慢、头过大、频繁超时,Nginx 会在后续轮询中主动跳过它,导致流量进一步向“看起来更稳”的低权重节点倾斜。
- 查 error.log 中 502 是否集中出现在某 IP:端口:
grep "502" /var/log/nginx/error.log | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+' | sort | uniq -c - 直连各后端,对比响应头大小:
curl -v http://ip:port/health 2>&1 | grep '^,超 4KB 可能触发 <code>upstream sent too big header - 检查该节点 CPU、连接数、accept queue 溢出情况(
netstat -s | grep "listen overflows"),确认它是否已实际过载











