轮询算法天然不保证路由一致性,因其仅维护一个循环指针、无状态记忆、不感知连接生命周期且多worker独立计数,导致同一客户端请求大概率散落到不同后端节点。

轮询分发本身不提供请求路由一致性,它按顺序循环转发,每次请求独立决策,相同客户端的多次请求大概率落到不同后端。
轮询为什么天然不保证路由一致
轮询只维护一个“当前指向哪台”的指针,每来一个新请求就推进一位,不记录来源、不绑定会话、不缓存映射关系。哪怕同一个浏览器连续刷新十次,只要 worker 进程指针步调不完全同步,就可能打散到全部后端节点上。
- 没有状态记忆:不保存 client IP、cookie 或 URI 与后端的对应关系
- 不感知连接生命周期:HTTP 短连接下,每次请求都是全新上下文
- 多 worker 并行:每个 worker 维护自己的指针,高并发时局部序列难以对齐
什么情况下看似“一致”其实是巧合
短时间少量请求出现重复落点,常被误认为有路由粘性,实际多是以下原因:
- 后端数量少(如仅2台),轮询周期短,容易在小样本中重复出现同一台
- 某台服务器响应慢或超时,触发健康检查摘除,剩余节点变少,命中概率升高
- 浏览器或 curl 复用连接(keepalive),但 Nginx 仍按轮询逻辑分发新请求,非路由绑定
需要一致性时该换什么策略
若业务要求同一用户始终访问同一后端(比如有本地会话、内存缓存或长连接依赖),轮询必须替换:
- ip_hash:按客户端真实 IP 哈希固定路由,简单有效,但 NAT 场景下易集中
- hash $cookie_sessionid:用登录态 cookie 做键,更精准适配用户维度
- 一致性哈希模块(如 consistent_hash):增删节点时仅局部重分配,适合动态扩缩容
- sticky session(需商业版或第三方模块):支持更复杂的会话保持机制
别强行让轮询“假装一致”
有人试图通过 weight=100 配置单台服务器、或用 backup+down 模拟主备,这既破坏轮询本意,又丧失冗余能力。真要一致性,就选匹配的算法;若只需均匀分摊,就坦然接受轮询的无状态本质——它不是缺陷,而是设计选择。



















