轮询模式下nginx按配置顺序循环“点名”分发请求,不依赖时间、负载或历史状态,仅靠轻量指针偏移实现确定性映射;重启后指针归零,故障节点被跳过,响应顺序由后端性能决定而非轮询本身。

轮询模式下,Nginx 并不按“请求到达时间”排队转发,而是靠一个轻量、无状态的内部指针,严格按 upstream 配置顺序循环“点名”——第1个请求给第1台,第2个给第2台,到末尾就回开头,不看响应快慢、不比连接数、也不记历史耗时。
轮询靠指针“点名”,不是靠时间或负载
这个指针不保存在内存共享区,也不依赖外部状态,每次分发完请求就自动下移一位;列表走完即归零,形成闭环。它不计算、不判断、不等待,纯粹是配置顺序 + 当前偏移量的确定性映射。
- 重启 Nginx 后指针重置为 0,从第一台开始重新计数
- 某台 server 被健康检查标记为不可用(如 max_fails 触发),指针会跳过它,继续往后走,不暂停、不回退
- 没有请求缓存或重排序机制,每个请求独立完成目标选择,毫秒级即时生效
看起来“乱序”,其实是后端响应节奏不同步
轮询只决定“发给谁”,不控制“谁先返回”。如果 server A 处理要 400ms,server B 只需 80ms,那么第2个发给 B 的请求很可能比第1个发给 A 的还早返回——这不是轮询失效,而是正常现象。
- 客户端看到的响应先后,取决于后端处理速度和网络往返延迟,与轮询无关
- 若某台长期响应慢,可能因连接堆积导致新请求排队,但轮询本身仍照常指派
- 真正影响感知顺序的,是后端性能差异、网络抖动、以及健康检查摘除节点带来的队列收缩
让轮询行为可预期的关键配置守则
轮询很守规矩,但容易被配置“带偏”。想让它稳定按顺序均分流量,必须清理干扰项:
- 所有 server 行必须裸写,不能含 weight=、backup、max_conns 等参数
- upstream 块顶部不能有 ip_hash、hash $arg_id、least_conn 等指令,注释掉也不行
- 每台 server 的健康检查参数要统一,例如都配 max_fails=2 fail_timeout=15s,避免一台松一台紧
- 验证实际分发目标,用 access_log 记录 $upstream_addr,而不是靠响应时间反推
轮询不是万能,但它是可靠起点
它不解决会话保持,也不适配异构集群;但它零配置启动、无运行时开销、逻辑完全透明。适合同构服务、灰度初期、或作为引入 least_conn 或主动健康探测前的基准对照。











