加权轮询不适用于websocket长连接,因其仅在握手时按权重分配,无法感知后续连接状态,易导致连接堆积与负载失衡;应改用least_conn或ip_hash等支持会话保持的算法,并配全http/1.1、upgrade头透传及长超时等基础配置。

加权轮询本身不适用于 WebSocket 长连接场景,排查失衡问题首先要确认是否误用了该策略——它按请求次数分配,而 WebSocket 连接建立后不再产生新请求,权重无法反映真实连接负载。
为什么加权轮询会导致 WebSocket 失衡
WebSocket 握手是一次性 HTTP 请求,之后所有数据帧都复用该 TCP 连接。Nginx 的加权轮询只在初始 proxy_pass 时生效,后续帧不会重新调度。这意味着:
- 权重高的节点可能在启动初期集中承接大量新连接,但连接长期驻留,无法动态释放到其他节点
- 权重设置无法感知后端实际连接数、内存占用或 CPU 压力,容易造成“高权低载”或“低权过载”
- 若客户端重连频繁(如网络抖动),仍走加权逻辑,但连接分布已偏离预期,加剧不均衡
如何验证当前是否真正在用加权轮询
检查 upstream 块中是否有 weight 参数且未启用 least_conn 或 ip_hash:
- 运行 nginx -T | grep -A 10 "upstream.*backend" 查看实时加载配置
- 确认 proxy_pass 目标是否指向该 upstream,且 location 块中无覆盖性调度指令
- 用 ss -tnp | grep :8080 | wc -l 分别统计各后端的 ESTAB 连接数,对比权重比例是否吻合(通常不吻合即说明策略失效)
真正适合 WebSocket 的替代方案
应切换为能感知连接状态的调度方式:
- least_conn:优先分发新连接到当前活跃连接数最少的节点,天然适配长连接累积特性
- ip_hash:保证同一客户端 IP 始终落在同一后端,适合需会话保持且客户端 IP 稳定的场景
- hash $http_sec_websocket_key:用 WebSocket 握手时的唯一 key 做哈希,比 IP 更精细,避免 NAT 下的会话错乱
配合配置的关键项不能漏
即使换算法,若基础代理参数缺失,仍会导致连接中断或超时掉线:
- 必须设置 proxy_http_version 1.1 和 Upgrade/Connection 头,否则握手失败
- proxy_read_timeout 和 proxy_send_timeout 建议设为 3600s 或更高,防止空闲连接被 Nginx 主动断开
- upstream 内启用 keepalive 32(数值按后端平均并发连接数 × 1.2 估算),提升连接复用率
- 禁用 proxy_buffering on,避免 WebSocket 数据帧被缓存延迟透传











