nginx默认轮询通过确定性指针循环实现均匀分担,不依赖响应快慢,仅维护各worker独立的顺序指针;需清除weight、ip_hash等干扰配置,并统一健康参数,长期统计偏差通常在1%~3%。

Nginx 默认轮询(Round Robin)本身就能实现请求的均匀分担,核心不靠智能判断,而靠确定性顺序和轻量状态管理——只要后端能力接近、配置干净、健康状态稳定,长期来看各节点接收请求数基本一致。
轮询靠“指针循环”,不是靠响应快慢
它不看 CPU、连接数或延迟,只维护一个指向当前 server 的内部指针:
- 收到第 1 个请求 → 发给 upstream 列表第 1 台,指针移到第 2 位
- 收到第 2 个请求 → 发给第 2 台,指针移到第 3 位
- 收到第 3 个请求 → 发给第 3 台,指针移到末尾后自动归零
- 故障节点会被自动跳过(需配合 max_fails/fail_timeout),轮询队列动态收缩但顺序不变
看起来不均?大概率是配置干扰了原始逻辑
轮询很守规矩,但一加修饰就变行为:
- 某台写了 weight=2 → 整个 upstream 变成加权轮询,不再是均等分配
- 启用了 ip_hash 或 hash $request_uri → 请求被固定路由,轮询失效
- 某台 max_fails=1,另一台没写或设为 max_fails=5 → 健康阈值不一致,导致轮询队列忽长忽短
让轮询真正稳住均匀性的实操要点
重点不在加功能,而在做减法、保一致:
- 所有 server 行删掉 weight、backup、down 等修饰,只留 IP 和端口
- upstream 块顶部确保没有 ip_hash、least_conn、hash 等指令(注释也不行,必须删除整行)
- 每台 server 显式配置相同健康参数,例如统一写 max_fails=2 fail_timeout=15s
- 用 $upstream_addr 记录到 access_log,发起 20+ 次请求后直接查日志,验证是否出现 A→B→C→A 的循环序列
worker 进程独立计数,短期波动属正常
每个 worker 维护自己的轮询指针,高并发时可能看到某台连续收几条请求——这是局部现象:
- 几百次以上请求的统计结果,各后端日志行数偏差通常在 1%~3%
- 若偏差持续超 10%,优先排查是否有节点因超时被反复摘除,或配置混入了 weight/ip_hash
- 无需调整 worker 数量来“修正”轮询,它本就不依赖全局同步计数











