加权轮询本身不引入调度延迟,仅按权重比例分发请求;观察到的“高并发下响应变慢”通常源于权重与后端真实能力不匹配或缺少健康检查、连接复用等配套机制,而非权重计算所致。

加权轮询本身不引入调度延迟,它只是按权重比例分发请求,不参与请求处理过程。你观察到的“高并发下响应变慢”,大概率不是权重计算拖慢了Nginx,而是权重配置与后端真实能力不匹配,或缺少配套机制,把后端或链路的瓶颈暴露得更明显。
看日志确认请求是否真按权重分配
别凭感觉判断权重有没有生效,直接查 access_log:
- 在 log_format 中加入 $upstream_addr 和 $request_time,例如:
log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_addr $request_time $upstream_response_time'; - 用 ab 或 wrk 发起 500+ 请求(-c 100 起步),再统计各后端 IP 的请求数和平均 $upstream_response_time
- 若 server A(weight=3)收到请求数远低于 server B(weight=1),说明有被动剔除(如 max_fails 触发)或主动健康检查失败,不是权重没起作用,而是它已被临时下线
查权重是否掩盖了节点性能差异
加权轮询假设你填的 weight 是准确的。但现实中,权重设高 ≠ 实际吞吐强:
- 旧机器 CPU 频率低、磁盘 I/O 慢、JVM GC 频繁,即使 weight=2,QPS 可能还不到新机器的一半
- 对比各节点的 $upstream_response_time 中位数和 P95:如果某台高权重节点 P95 耗时是其他节点的 3 倍,那它正在拖累整体延迟,权重反而放大了问题
- 建议用实测 QPS 设权重——比如压测得出 server A 稳定承载 800 QPS、server B 承载 400 QPS,则 weight 应设为 2:1,而非按 CPU 核数 4:2 凭空估算
验证 worker 层是否存在局部倾斜
Nginx 每个 worker 进程维护独立的轮询指针,高并发下可能出现短时集中打向同一后端:
- 启用 nginx_status(需编译含 stub_status 模块),访问 /nginx_status,关注 Active connections 和 Waiting 数值
- 若某个 worker 的 Waiting 连接数长期高于其他 worker 2 倍以上,说明请求未被均匀接纳,可能触发了 accept_mutex 锁竞争或 epoll 边缘触发异常
- 检查是否配置了 accept_mutex on(默认开启),高并发下它会抑制惊群,但也可能造成调度延迟;可尝试设为 off 并配合 multi_accept on 测试效果
排除超时与重试带来的隐性延迟
加权轮询不控制重试逻辑,但 proxy_next_upstream 会改变实际调度路径:
- 若配置了 proxy_next_upstream error timeout,且某后端频繁超时,Nginx 会在单次请求内尝试多个节点,$request_time 就包含多次建连、等待、失败的时间总和
- 检查日志中是否有大量 upstream timed out 或 no live upstreams,这说明权重节点已集体不可用,流量被迫排队或回退到备用 upstream
- 限制重试次数:加上 proxy_next_upstream_tries 2 和 proxy_next_upstream_timeout 6s,避免单请求耗尽所有上游











