加权轮询不提供请求粘性,仅按权重比例长期均衡分发请求;所谓“粘性”是http长连接、缓存或日志偏差等外部因素导致的假象,真正实现粘性需用ip_hash、cookie哈希或sticky cookie等机制。

加权轮询本身不提供请求粘性,它只是按权重比例分配请求的调度策略。所谓“请求粘性误区”,常指运维或开发误以为加权轮询能保证同一客户端(比如同一个浏览器、同一个IP)后续请求总落到同一台后端服务器上——这其实是ip_hash或会话保持机制的功能,不是加权轮询的责任。
加权轮询的本质是概率性流量分发
它基于权重做长期趋势上的比例控制,而非绑定关系。例如:
- 配置 server A weight=3、B weight=2、C weight=1,理论请求占比为 50% / 33% / 17%
- Nginx 实际采用平滑加权轮询算法(smooth weighted round-robin),避免请求在某一轮内扎堆打到高权值节点
- 单次请求落哪台机器,取决于当前调度轮次和内部计数器,与客户端特征无关
为什么你会观察到“看似粘性”的现象
这不是加权轮询的设计行为,而是外部因素干扰导致的假象:
- 浏览器复用连接(HTTP Keep-Alive):一个客户端发起多个请求,可能复用同一个 TCP 连接,而 Nginx 默认对长连接内的子请求仍走相同 upstream server(尤其在 proxy_http_version 1.1 + keepalive 启用时)
- 客户端缓存或代理层干扰:CDN、前置网关、测试工具(如 curl 不带 -H "Cache-Control: no-cache")可能缓存响应,让你误判后端处理节点
- 日志采样偏差:只看几条访问日志,容易把随机分布误读为固定路由;应统计数百次以上请求的 IP→后端映射分布
- 后端服务自身重定向或跳转:比如登录成功后 302 到固定域名,掩盖了原始负载均衡路径
如何验证加权轮询是否正常工作
绕过干扰项,直击 upstream 调度逻辑:
- 用 curl -H "Connection: close" 强制每次新建连接,排除 Keep-Alive 影响
- 在每台后端服务器的响应头中注入唯一标识,例如 X-Backend-ID: server-a,再用脚本批量请求并统计分布
- 检查 Nginx error 日志是否有 upstream timed out 或 no live upstreams,确认健康检查未误剔节点
- 确认没有意外启用 ip_hash、hash $remote_addr 等会话保持指令——它们会覆盖加权轮询
真正需要粘性时该怎么做
如果你确实需要“同一用户始终打到同一台后端”,加权轮询不能满足,要换策略:
- 用 ip_hash:简单粗暴,但受 NAT、代理影响大,且无法结合权重
- 用 hash $cookie_jsessionid 或 hash $arg_token:基于业务标识做一致性哈希,更精准
- 用 sticky cookie(需 nginx-plus 或 openresty):服务端下发路由 cookie,支持权重+粘性双目标
- 后端自己做 session 共享(Redis 存 session):解除粘性依赖,让加权轮询真正发挥弹性分流作用











