nginx轮询算法仅保证长期统计下的请求均匀分发,不追求绝对平均;其通过顺序指针循环调度,不依赖实时指标,偏差≤3%属正常,超限需排查weight、ip_hash或健康检查等干扰项。

Nginx 轮询算法本身不追求“绝对平均”,它只保证长期统计意义下的请求分发均匀性。出现各节点请求数略有偏差(比如三台服务器分别收到 332、335、333 次请求),是完全正常且符合设计预期的。
这背后有几个关键点需要理解:
轮询是顺序指针,不是实时调控器
Nginx 在 upstream 中维护一个循环指针,每次新请求到来就指向下一个 server,到末尾归零。它不读取任何实时指标——不看响应快慢、不查连接数、不评估 CPU。所以它无法做到“刚好分完再重来”,而是在真实流量流中持续推进。短时间样本(比如 10 次请求)必然有波动;只有在数百甚至上千次请求后,分布才趋近理论均值。
偏差 ≤3% 属于正常范围
官方和实测经验都表明:在配置干净、后端稳定、健康检查统一的前提下,长期运行下各节点请求数偏差控制在 ±3% 内,即视为轮询生效。例如 1000 个请求,330–340 次/台就是理想状态。超过这个范围,才需排查问题。
真正影响“看起来不均”的常见干扰项
- 某台 server 行写了 weight=2:立刻变成加权轮询,不再是均等
- 启用了 ip_hash 或 hash $request_uri:请求被固定路由,轮询失效
- 某台因超时触发 max_fails 被临时摘除:轮询队列变短,剩余节点自然多接请求
- 后端启用了 keepalive:单个 TCP 连接复用多次请求,日志里“请求数均”但“连接数不均”,造成误判
验证是否真不均,不能靠感觉
直接查 Nginx 的 $upstream_addr 日志字段,发起 ≥1000 次串行短连接请求(如 ab -c 1 -n 1000),统计每台后端出现频次。若结果偏离明显(如 450 / 300 / 250),再回头检查配置是否干净、健康检查是否对齐、后端是否真在线且响应正常。
轮询的“不绝对平均”,恰恰说明它轻量、确定、可预期——它不试图聪明地干预,而是把公平交给稳定的环境和干净的配置。











