默认轮询即可实现平稳分流,关键在于清理weight、ip_hash等干扰项,统一max_fails和fail_timeout参数,并通过日志验证循环分发序列,同时理解worker进程独立计数导致的短期波动属正常现象。

默认轮询就能实现平稳分流,关键不是加功能,而是清干扰、保一致、验结果。
确保 upstream 配置真正“干净”
轮询只认 server 行的排列顺序,任何修饰都会改变行为:
- 删掉所有 weight= 参数:哪怕只有一台写了
weight=1,整个组就变成加权轮询 - 彻底移除 ip_hash、hash $arg_id、least_conn 等指令:注释也不行,必须整行删除
- 每台 server 保持最简格式,例如:
server 192.168.1.10:8080;,不带backup、down、max_fails等修饰
统一健康检查参数防“隐形偏斜”
轮询本身不感知状态,但健康检查配置不一致会让某台服务器频繁被剔除,导致实际流量倾斜:
- 为每台 server 显式加上相同探测参数:
max_fails=2 fail_timeout=15s - 避免 A 服务器用
max_fails=1、B 用max_fails=5这类不对齐配置 - 这样所有节点在异常时被摘除的门槛一致,轮询队列才稳定
用日志直接验证分发序列
别靠平均响应时间或肉眼观察判断,真实流向必须靠日志确认:
- 在 http 块中定义日志格式:
log_format upstream_log '$remote_addr - $upstream_addr [$time_local] "$request" $status'; - 在 location 中启用:
access_log /var/log/nginx/upstream.log upstream_log; - 发起 10+ 次请求(如 curl 或浏览器刷新),查看日志是否呈现循环序列,例如:
192.168.1.10→192.168.1.11→192.168.1.12→192.168.1.10
理解 worker 进程独立计数带来的短期波动
Nginx 每个 worker 进程维护自己的轮询指针,高并发瞬间可能出现局部连续打到同一台:
- 这是正常现象,不是配置错误
- 长期统计(几百次以上请求)下,各后端 access.log 行数差异通常控制在 1%~3%
- 若偏差持续超过 10%,优先检查是否有节点因超时被临时摘除,或配置里混入了 weight/ip_hash











