nginx默认轮询通过固定顺序指针实现请求均匀分发,不依赖响应时间或负载状态;若出现不均,多因weight、ip_hash或健康检查配置干扰,需清除冗余参数并统一探测设置。

Nginx 默认轮询(Round Robin)不是靠实时计算或状态感知来“动态调优”,而是用一个轻量、确定、无状态的指针机制,严格按配置顺序循环分发请求。它本身不聪明,但足够可靠——只要后端一致、配置干净,长期来看每台服务器承接的请求数基本相等。
轮询靠“指针”不靠“判断”
它不看响应快慢、不查连接数、不读CPU负载,只维护一个当前指向哪台服务器的内部位置标记:
- 第1个请求 → 发给 upstream 列表中第1行 server
- 第2个请求 → 发给第2行 server
- 第3个请求 → 发给第3行 server
- 到末尾后自动回到开头,继续循环
这个过程没有随机、没有计时、没有反馈闭环,纯线性推进,因此开销极低,也容易预测和验证。
为什么有时看起来不均匀?常见干扰项
轮询本身不会偏心,但以下配置会悄悄改变它的行为:
-
weight 参数存在:哪怕只有一台写了
weight=2,整个 upstream 就切换为加权轮询,不再是均等分配 - ip_hash 或 hash 指令启用:请求被绑定到固定节点,轮询顺序完全失效
-
健康检查阈值不统一:某台因
max_fails=3被频繁摘除,而另一台用max_fails=1更早下线,导致轮询队列长度波动,剩余节点自然多扛流量 - server 行含 down 或 backup 标记:这些节点不参与轮询,实际参与分发的机器变少,均匀性在更小集合内重新分布
让轮询真正均匀的关键操作
重点不是加功能,而是清理和对齐:
- 删掉所有
weight=、max_fails=、fail_timeout=以外的参数;每行server只保留 IP 和端口 - 确认 upstream 块顶部没
ip_hash、least_conn、hash $xxx等指令——注释掉不算清除,必须整行删除 - 为每台 server 显式配置一致的探测参数,例如统一写
max_fails=2 fail_timeout=15s - 用
$upstream_addr记入 access_log,直接查看每次请求实际落到哪台,比观察监控图表更准、更及时
轮询适合什么场景,不适合什么
它天然适配同构环境:
- 容器化部署中,所有 Pod 镜像、资源限制、启动时间一致
- 灰度发布初期,新旧版本能力接近,暂不需要按性能差异化分流
- 无状态 API 服务,单次请求耗时方差小,不依赖会话保持
但它不解决这些问题:
- 服务器硬件老化程度不同,处理能力明显失衡
- 部分接口响应极慢(如报表导出),拖累整条轮询链路节奏
- 需要用户会话始终落在同一台机器(这时该用 ip_hash 或外部 session 存储)
轮询是起点,不是终点。用稳了,再叠加 least_conn 或主动健康检查,才真正可控。











