加权轮询权重不生效通常因配置被静默忽略或覆盖,需检查拼写错误、指令冲突(如ip_hash)、运行时分发比例及健康状态;nginx -t不报错不代表weight生效,应以nginx -T输出和实际流量分布为准。

加权轮询权重不生效,通常不是 Nginx 拒绝执行,而是配置被静默忽略或被其他规则覆盖。关键要区分“语法错误”和“语义失效”——nginx -t 不报错,但 weight 就是不起作用,这才是最常见也最易被忽视的问题。
检查 weight 指令是否拼写正确
Nginx 对指令名极其敏感,错一个字母就直接忽略整行,且不报错、不警告:
- weight 写成 weigth、wight、weights → 该 server 的权重退为默认值 1
- max_fails 写成 max_fail 或 maxfails → 健康检查失效,节点异常时不会被自动摘除
- fail_timeout 写成 fail_time_out、failtout → 故障隔离时间失效,节点持续接收流量
用 nginx -T | grep -A5 "upstream.*api" 查看最终生效的 upstream 配置,确认每行 server 后面实际解析出的 weight 值是多少(注意:-T 输出的是合并后的真实配置,比编辑的源文件更可信)。
确认没有其他指令覆盖或禁用权重
权重只在纯轮询上下文中起作用,以下情况会直接让 weight 失效:
- upstream 块中启用了 ip_hash、hash $cookie_session 或 least_conn → 加权轮询被完全跳过
- 部分 server 写了 weight=3,另一些没写 weight → 它们默认是 1,看似有差异,但若混用 backup 或 down,权重逻辑可能被中断
- server 行末尾多了空格或换行,例如:
server 10.0.0.1:8000 weight=2
; → Nginx 解析失败,整行被忽略
验证运行时分发是否匹配预期比例
日志或监控数据才是最终裁判。别只信配置,要看真实请求落到哪台机器:
- 启用 stub_status,访问
/nginx_status,查看各 server 的Active和Requests计数比是否接近 weight 比(如 weight=3 和 weight=1 应接近 3:1) - 在每个后端响应头中加唯一标识:
add_header X-Node "A";,然后用 curl 循环 100 次并统计:for i in {1..100}; do curl -sI http://upstream/ | grep X-Node; done | sort | uniq -c - 如果分布严重偏离(比如 3:1 的配置跑出 1:1),而 error.log 里又没有相关报错,基本可锁定 weight 未加载
排除连接复用与健康检查干扰
表观“权重没生效”,有时只是观测方式不对:
- 客户端复用 keepalive 连接,Nginx 可能将后续请求持续打到同一后端 → 关闭 upstream 的 keepalive,或改用短连接压测(如 wrk -d10s --connections 1)
- 某节点因超时或非 2xx 响应触发 max_fails,进入 fail_timeout 状态 → 它暂时不参与轮询,权重再高也没用;查 error.log 中是否有
upstream timed out或no live upstreams - 所有 server 都没配 max_fails/fail_timeout,但其中一台实际响应慢 → Nginx 会不断重试它,导致其他节点流量偏低,看起来像“权重失衡”


















