加权轮询权重失效常因upstream域名被Nginx静态DNS缓存所致,表现为请求始终打到首个解析IP;需检查是否用域名定义server、配置合法resolver、proxy_pass引用变量、valid参数合理,并排除keepalive连接池干扰。

加权轮询权重失效,有时并非配置写错或节点异常,而是 upstream 域名被 Nginx 静态缓存,导致所有请求始终打到解析出的首个 IP 上——看起来像“只走一台”,实则是 DNS 缓存掩盖了轮询逻辑。这种问题在使用域名定义 upstream 时高频出现,且无错误日志,极难察觉。
确认 upstream 是否用了域名而非 IP
检查 upstream 块中是否直接写了域名:
-
错误写法:
server api.example.com:8080 weight=3;—— 启动时仅解析一次,后续永远固定指向首次返回的 A 记录(哪怕该 IP 已下线) -
正确写法:要么全用 IP(
server 192.168.1.10:8080 weight=3;),要么启用动态解析机制
验证 DNS 解析是否真的在更新
仅靠 nginx -t 或 reload 无法触发域名重解析。需主动验证:
- 执行
nginx -T | grep "upstream\|server",确认配置中是否含域名;再查是否有resolver指令(必须存在且位置合法) - 用
dig api.example.com +short对比当前真实 DNS 返回,再查 Nginx error.log 中是否出现resolver timed out或no address类提示 - 临时在 location 中加
add_header X-Resolved-IP "$upstream_addr";,发起多次请求看响应头是否始终一致(若一致,说明没轮转,大概率是静态解析)
检查 resolver 配置是否满足三要素
动态解析不是加一行 resolver 就生效,必须同时满足:
-
作用域正确:resolver 必须放在
http、server或location块内,不能只写在 upstream 块里 -
变量触发:proxy_pass 必须引用变量(如
set $backend "api.example.com"; proxy_pass http://$backend:8080;),硬编码域名不触发运行时解析 -
valid 参数合理:例如
resolver 8.8.8.8 valid=5s;,若设为valid=300s,DNS 变更后最长要等 5 分钟才生效
排除 upstream 连接池复用干扰
即使 DNS 动态更新了,Nginx 默认会复用已建立的连接池,导致新解析出的 IP 长期不被使用:
- 检查是否启用了
keepalive连接池(如upstream backend { keepalive 32; }),它会优先复用旧连接,跳过轮询调度 - 临时禁用连接池测试:注释掉
keepalive行,或加proxy_http_version 1.0;和proxy_set_header Connection '';强制短连接 - 观察 access_log 中
$upstream_addr字段是否开始出现多个不同 IP,确认轮询真正启动











