Nginx默认轮询是确定性循环链表遍历,依靠内部指针按upstream配置顺序逐台分发请求,到末尾回绕;重启后指针归零,运行中持续跟踪位置,自动跳过故障节点,受weight、ip_hash或健康检查不一致干扰会导致偏离均匀分布。

Nginx 默认轮询(Round Robin)不是靠时间或随机决定,而是严格按配置顺序“点名”,用一个内部指针逐台推进,到末尾就回绕——本质是确定性的循环链表遍历。
轮询怎么一步步走?
它不看响应快慢、连接数多少,只认 upstream 块里 server 的书写顺序和当前指针位置:
- 第 1 个请求 → 发给列表第 1 台 server(指针指向第 1 台)
- 第 2 个请求 → 指针下移,发给第 2 台
- 第 3 个请求 → 指针再下移,发给第 3 台
- 第 4 个请求 → 列表已到尾,指针归零,重新发给第 1 台
指针状态怎么维持?
这个指针在 Nginx 进程运行期间持续存在,不依赖定时器或计数器重置:
- 重启 Nginx 后,指针会从头开始(即第 1 个新请求一定落到第 1 台)
- 运行中,指针始终记住“上次轮到谁”,下次直接接着走
- 若某台 server 因健康检查失败被临时摘除(如 max_fails 触发),指针自动跳过,不计入循环步长
为什么有时感觉没按顺序分?
真正打乱轮询节奏的,往往不是算法本身,而是配置干扰:
- 写了 weight=2 → 立刻切换为加权轮询,不再均等
- 启用了 ip_hash 或 hash $request_uri → 请求被固定路由,轮询失效
- 各 server 的 max_fails / fail_timeout 参数不一致 → 健康状态判定不同步,导致可用节点数动态变化
如何验证当前确实是轮询?
别猜,用日志看真实流向:
- 在 location 块中启用 access_log,并记录 $upstream_addr
- 观察连续请求的日志输出,应呈现严格循环模式(如 101→102→103→101…)
- 若出现重复或跳序,说明有 weight、ip_hash 或健康状态不一致在起作用


















