websocket代理在nginx中需适配长连接特性,必须配置proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade和connection $connection_upgrade;推荐least_conn算法,慎用ip_hash;超时与健康检查须按长连接重设。

WebSocket 代理在 Nginx 中集成负载均衡算法,关键不是“选哪个算法”,而是让算法适配长连接的本质——连接一旦建立,后续所有帧必须路由到同一台后端,否则会断连。Nginx 原生支持(1.3.13+),但默认轮询不适用,需按连接生命周期特性主动适配。
必须启用的协议透传机制
无论用哪种算法,以下三项是 WebSocket 代理的前置基础,缺一不可:
- proxy_http_version 1.1:强制使用 HTTP/1.1,这是 Upgrade 协议升级的前提
- proxy_set_header Upgrade $http_upgrade:原样透传客户端的 Upgrade 头(值为 websocket)
- proxy_set_header Connection $connection_upgrade:配合 map 指令动态设置,避免硬写 "upgrade" 导致普通 HTTP 请求异常
least_conn 是最推荐的调度算法
WebSocket 连接持续时间长、并发数高,轮询会把新帧误分到其他节点;least_conn 按当前活跃连接数分发,天然契合长连接场景:
- 后端服务器连接数实时可查(可通过 nginx_stub_status 或 Prometheus 抓取)
- 避免单节点堆积数千空闲连接,提升资源利用率
- 无需 session 共享或外部状态同步,部署简单
- 配合 keepalive 32 可复用与后端的空闲连接池,降低建连开销
ip_hash 仅适用于特定约束场景
它能保证同一 IP 的所有连接始终落在同一台后端,实现会话粘滞,但有明显局限:
- 局域网出口 IP 相同(如企业内网、校园网)会导致流量严重倾斜
- 前端有 CDN 或代理时,$remote_addr 变成代理 IP,失去区分能力
- 后端宕机时连接无法自动迁移,会话直接丢失
- 不支持权重配置,无法应对服务器性能差异
超时与健康检查必须重设
WebSocket 不是请求-响应模型,传统 HTTP 健康检查和默认超时会误杀连接:
- 禁用 max_fails/fail_timeout:HTTP GET 探针无法反映 WebSocket 服务真实状态,建议改用 TCP 层探测(如 stream 模块的 health_check)
- proxy_read_timeout 和 proxy_send_timeout 设为业务最大空闲时长(例如 86400 表示 24 小时),而非默认 60 秒
- proxy_connect_timeout 保持合理即可(如 30 秒),只控制初始握手建连阶段











