nginx支持websocket需三要素:透传upgrade/connection头部实现101升级、设proxy_read_timeout等超时为长连接(如86400s)、启用ip_hash或sticky cookie确保同一连接始终路由至同一后端。

要让 Nginx 负载均衡器真正支持 WebSocket 持久化连接,关键不是“打开开关”,而是让整个代理链路匹配 WebSocket 的协议行为:一次握手、长期复用、双向帧流。配置失误常导致 101 升级失败、60 秒准时断连、或同一连接被轮询到不同后端而消息丢失。
必须透传的协议升级头
WebSocket 握手本质是 HTTP 请求升级,Nginx 必须原样传递关键头部,否则后端收不到升级意图:
- proxy_http_version 1.1:HTTP/1.0 不支持 Upgrade,这句是前提
- proxy_set_header Upgrade $http_upgrade:把客户端发来的 Upgrade: websocket 头传下去
- proxy_set_header Connection $connection_upgrade:配合 map 指令动态设置,避免硬写 "upgrade" 导致普通 HTTP 请求异常(推荐写法)
漏掉任意一项,浏览器 Network 面板里看到的状态码会是 200 而非 101,或者直接报 Handshake failed。
必须延长的超时时间
WebSocket 没有“请求-响应”周期,空闲时无数据流。Nginx 默认 proxy_read_timeout 60 秒会主动断开连接:
- proxy_read_timeout 86400(24 小时):控制 Nginx 等待后端数据的最大时长,应略大于业务最大空闲间隔(如心跳间隔 × 2)
- proxy_send_timeout 86400:防止大消息分片发送卡住被中断
- proxy_connect_timeout 30:仅影响初始建连,保持合理即可,无需设过大
注意:这些值不是越大越好,需结合监控(如 nginx_stub_status)观察实际连接存活情况后调优。
必须启用的连接保持策略
WebSocket 连接建立后,所有后续帧(包括 ping/pong)必须路由到同一台后端。默认轮询会导致“连接漂移”,后端无上下文直接断连:
- ip_hash:最简方案,按客户端 IP 哈希固定后端;适合内网或公网直连场景,但局域网 NAT 后易倾斜
- sticky cookie:后端在握手成功后 Set-Cookie(如 ws_route=server-02),Nginx 用 sticky 指令识别并绑定;兼容 CDN、移动端、动态 IP,生产环境更稳妥
- least_conn + 后端共享状态:若无法做粘滞,可改用 least_conn 调度,但后端需用 Redis 统一管理 session 和连接映射
不配连接保持,即使头部和超时全对,也只解决“断连”问题,不解决“错连”问题。
upstream 层适配长连接特性
后端集群本身也要为长连接优化:
- keepalive 32(或更高):维持与每台后端的空闲连接池,减少重复 TCP 握手开销
- 禁用 max_fails/fail_timeout 默认健康检查:HTTP GET 探针无法反映 WebSocket 实际可用性;建议改用 TCP 探活,或启用 nginx plus 的 health_check 指令(interval=10s fails=3 passes=2)
- 慎用 weight 或 backup:权重调度在长连接下意义有限;backup 节点需确保能承接 WebSocket 连接状态
不复杂但容易忽略











