Nginx反向代理WebSocket需显式延长超时(proxy_read_timeout和proxy_send_timeout设为86400)、透传Upgrade/Connection头部、启用ip_hash或cookie会话保持,并关闭buffering与cache。

反向代理 WebSocket 时,超时控制和会话保持是维持长连接稳定的核心。默认配置下,Nginx 或 Apache 很容易在空闲几十秒后主动断开连接,导致“秒断”“504”或消息丢失;而多个后端节点间若无会话粘滞,客户端重连可能落到不同服务实例,造成状态不一致或认证失效。
关键超时参数必须显式延长
Nginx 默认的 proxy_read_timeout 和 proxy_send_timeout 均为 60 秒,这对 WebSocket 是致命的——只要连接空闲超过该值,Nginx 就会关闭 TCP 连接,后端完全不知情。
-
proxy_read_timeout:设为 86400(24 小时),表示两次读操作之间允许的最大间隔,应大于服务端心跳周期(如 Swoole 的
heartbeat_idle_time) - proxy_send_timeout:同样设为 86400,保障大消息或弱网环境下发送不被中断
- proxy_connect_timeout:建议设为 10–30 秒,避免高并发建连失败
协议升级头必须透传且精准构造
WebSocket 握手依赖 HTTP/1.1 的 Upgrade 机制,Nginx 若未正确转发相关头部,握手直接失败,返回 200 而非 101。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 必须启用 proxy_http_version 1.1
- 用 proxy_set_header Upgrade $http_upgrade 原样传递客户端 Upgrade 头
- 用 proxy_set_header Connection "upgrade" 固定设置(不能写
$http_connection,否则可能继承 keep-alive) - 推荐在 http 块中添加 map 指令预处理:
map $http_upgrade $connection_upgrade { default upgrade; '' close; },再在 location 中写proxy_set_header Connection $connection_upgrade;,更健壮
负载均衡场景下必须启用会话保持
当后端是多实例 WebSocket 服务(如集群部署的 Swoole 或 Spring Boot),一次连接必须始终落在同一台机器上——因为 WebSocket 连接状态、用户上下文、内存 Session 都不共享。
- Nginx 使用 ip_hash 最简单,但不适用于有前置 CDN 或代理的场景
- 更可靠的是基于请求路径或 Cookie 的 sticky:例如后端在握手成功后下发
Set-Cookie: route=ws-01,Nginx 配置sticky cookie route expires=1h domain=.example.com path=/; - Apache 则需配合 mod_proxy_balancer 与
stickysession=routeid,并在后端响应中注入routeid值(如 JSESSIONID 或自定义 header)
禁用干扰长连接的代理行为
WebSocket 是全双工隧道,不是 HTTP 请求流,所有面向短连接优化的策略都需关闭。
- 必须设置 proxy_buffering off,否则帧会被缓存,破坏实时性
- 严禁使用
proxy_cache相关指令——WebSocket 消息不可缓存 - 不要在 Nginx 层加
add_header Access-Control-Allow-Origin,CORS 应由后端在 101 响应中返回,Nginx 默认透传即可 - 可选:添加
tcp_nodelay on;减少小包延迟(对高频 ping/pong 有效)

















