Nginx不支持WebSocket多路复用,仅作连接级代理;需透传Upgrade头、启用ip_hash或sticky cookie实现连接粘滞,并调大proxy_read_timeout等超时参数以保障长连接稳定。

直接说结论:Nginx 本身不支持 WebSocket 的“多路复用”(即单个 TCP 连接承载多个逻辑 WebSocket 子通道),它只做连接级代理。所谓“多路复用的 WebSocket 负载均衡”,实际是指在多个后端实例间,对大量独立的 WebSocket 连接做高可用、低中断、长生命周期的负载分发。核心不是复用,而是稳定透传 + 连接粘滞 + 超时适配。
必须透传协议升级头
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 机制,Nginx 默认行为会破坏它:
- proxy_http_version 1.1:强制使用 HTTP/1.1,这是 Upgrade 的前提,不能省略
- proxy_set_header Upgrade $http_upgrade:变量名必须小写,$http_upgrade 是 Nginx 内置变量,代表客户端原始 Upgrade 头值
- proxy_set_header Connection "upgrade":值必须是字面量 "upgrade",不能写成 $connection_upgrade(除非你额外定义了 map 块)
必须启用连接保持策略
WebSocket 是长连接,一次建立后持续收发帧。若用默认轮询,后续 Ping/Pong 或业务帧可能被分到不同后端,导致连接失效或消息丢失:
- ip_hash:最简单可靠,按客户端 IP 哈希固定路由,适合公网 IP 相对稳定的场景
-
sticky cookie:更精细,例如
sticky cookie srv_id expires=1h domain=.example.com path=/;,适合需跨 CDN 或 NAT 的环境 - 避免使用
least_conn或轮询——它们面向短请求,不适用于连接生命周期管理
必须调大超时并禁用干扰行为
空闲 WebSocket 连接可能数小时无数据,Nginx 默认超时(60s)会主动断连:
- proxy_read_timeout 86400(24 小时):控制后端无响应时 Nginx 断连时间,建议设为业务最大空闲容忍时长
- proxy_send_timeout 86400:同理,防止发送卡住导致连接中断
- proxy_buffering off(可选):禁用缓冲,确保 Ping/Pong 和实时消息零延迟透传
- 不要设置
proxy_cache或proxy_redirect,WebSocket 不走缓存路径
完整 upstream + location 示例
以下配置已用于生产环境,支持百级并发 WebSocket 实例:
upstream ws_backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
keepalive 32; # 与每个后端保持的空闲长连接数
}
<p>server {
listen 443 ssl;
server_name api.example.com;</p><pre class='brush:php;toolbar:false;'>location /ws/ {
proxy_pass http://ws_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400;
proxy_send_timeout 86400;
proxy_connect_timeout 30;
proxy_buffering off;
}}


















