Nginx支持WebSocket负载均衡需同时满足三要素:透传Upgrade/Connection头部实现101升级、设proxy_read_timeout等超时为长连接(如86400s)、启用ip_hash或sticky cookie确保同一连接始终路由至同一后端。

要让 Nginx 正确支持 WebSocket 的负载均衡,关键不是“开启某个开关”,而是三类配置必须同时到位:协议升级头透传、连接保持策略、超时参数调优。缺一不可,否则会出现握手失败、60 秒准时断连、消息被发到错误后端等问题。
必须配置的三个核心头部
WebSocket 握手本质是 HTTP/1.1 的 Upgrade 请求,Nginx 默认不透传相关头,必须显式设置:
- proxy_http_version 1.1:强制启用 HTTP/1.1,这是 Upgrade 机制的前提;HTTP/1.0 不支持升级,设了也没用
- proxy_set_header Upgrade $http_upgrade:变量名必须小写 $http_upgrade,大写 $HTTP_UPGRADE 会失效;它把客户端原始的 Upgrade 头(如 websocket)原样传给后端
- proxy_set_header Connection "upgrade":值必须是双引号包裹的字面量 "upgrade",不能写成 $connection_upgrade(除非你额外定义了 map 块),否则 Nginx 会尝试变量替换并报错
必须启用连接保持(Session Stickiness)
WebSocket 是单次握手、长期复用的 TCP 连接,所有后续帧都必须路由到同一台后端。轮询(round-robin)会导致帧被分发到不同节点,后端无上下文,直接丢弃或拒绝。
- ip_hash:最简方案,适合客户端直连、无 CDN/NAT 的环境;但运营商级 NAT 或公司内网下,大量用户共用一个出口 IP,会造成单点压垮
- sticky cookie srv_id expires=1h path=/:更稳妥,Nginx 在首次响应中种 cookie,后续请求按 cookie 路由;需编译时启用 ngx_http_sticky_module 或使用 Nginx Plus
- 自定义 Header + hash:后端在握手成功响应中返回 X-WS-Node: node-a,Nginx 用 map 提取并做 hash 路由;适合需要精细控制的场景
必须延长超时时间
WebSocket 没有“响应”概念,只有持续帧流。Nginx 默认 proxy_read_timeout 60s 会在空闲时主动断开连接,造成“准时 60 秒断连”现象。
- proxy_read_timeout:建议设为 86400(24 小时)或更长,至少 ≥ 前端心跳间隔 × 2
- proxy_send_timeout:同样设为 86400,防止大消息分片发送中途被掐断
- keepalive_timeout:可选但推荐一致,保持客户端到 Nginx 的连接存活
配套建议:健康检查与 keepalive
避免将新连接转发到已断连的后端节点,提升可用性:
- 在 upstream 块中加 health_check interval=10s fails=3 passes=2(需启用 ngx_http_upstream_health_check_module)
- 启用后端连接池复用:keepalive 32,减少 TCP 握手开销
- HTTPS 场景下,确保证书链完整、TLS 版本明确(如 ssl_protocols TLSv1.2 TLSv1.3),并禁用 HTTP/2(部分版本存在兼容问题)


















