nginx加权轮询偏差需通过配置检查、日志分析和短连接压测综合排查:确保weight为正整数、禁用keepalive、使用最小配置隔离验证,并确认后端健康状态与nginx版本≥1.19.0。

排查 Nginx 加权轮询(weighted round-robin)中权重比例计算错误,核心是确认请求分发是否符合预期权重比,并定位偏差来源。Nginx 本身不提供实时权重分配日志,需结合配置检查、日志分析和请求追踪综合判断。
检查 upstream 配置是否符合加权轮询语义
Nginx 的加权轮询不是“严格按比例每 N 次请求切分”,而是基于内部计数器(current_weight)的动态调度算法:每个节点有 weight 和运行时 current_weight,每次选 current_weight 最大的节点,然后更新其 current_weight -= total_weight,其余节点 current_weight += weight。这意味着:
- 权重必须为正整数(浮点或负值会被截断为 0,导致节点失效)
- 小权重组合(如
weight=1和weight=2)在短周期内可能呈现明显非均匀分布,属正常行为 - 若所有节点 weight 相同,实际退化为普通轮询,无需额外验证
- 配置中不能混用
ip_hash、least_conn等其他负载策略,否则加权轮询不生效
开启并分析 access_log 中 upstream 信息
在 server 或 location 块中启用带 upstream 变量的日志,例如:
log_format upstream_log '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" "$http_user_agent" ' '
"$upstream_addr" "$upstream_cache_status" "$upstream_http_x_backend" ' '
"$upstream_response_time" "$upstream_header_time" "$upstream_connect_time"';
然后使用 awk 或简单脚本统计各后端 IP 的请求占比:
注意:$upstream_addr 包含 IP:PORT,若后端用了域名且 DNS 解析为多个 IP,需先固定解析或改用 upstream_http_* 自定义响应头标识实例。
排除连接复用与长连接干扰
HTTP/1.1 keepalive 和 upstream 的 keepalive 指令会导致单个客户端连接反复打到同一后端,掩盖权重分布。验证时应:
- 临时关闭客户端 keepalive(如 curl 加
-H "Connection: close") - 在 upstream 块中设置
keepalive 0;(禁用连接池) - 用多个并发客户端(如
ab -n 1000 -c 100或hey -n 1000 -c 100)发起短连接请求,避免单连接复用影响统计
用最小可复现配置隔离验证
新建独立配置片段,仅包含最简 upstream 和 server,例如:
upstream test_backend {server 127.0.0.1:8081 weight=3;
server 127.0.0.1:8082 weight=1;
}
server {
listen 8080;
location / {
proxy_pass http://test_backend;
proxy_set_header Host $host;
}
}
配合两个简单 HTTP 服务(如 Python -m http.server),用脚本连续请求 100 次,观察响应来源分布。若仍严重偏离 3:1(如变成 50:50),需检查:
- 后端服务是否健康(
max_fails/fail_timeout导致某节点被临时摘除) - 是否存在
down、backup标记干扰权重计算 - Nginx 版本是否过旧(早期版本对 weight 处理有边界 bug,建议 ≥1.19.0)











