要让nginx代理websocket满足高实时要求,关键是避免中断、减少延迟抖动、保障连接稳定性;需透传upgrade和connection头、设proxy_read_timeout和proxy_send_timeout为86400、关闭proxy_buffering和gzip、禁用proxy_cache,并验证握手状态码为101。

要让 Nginx 代理 WebSocket 满足高实时要求,关键不是“加速”,而是**避免中断、减少延迟抖动、保障连接稳定性**。WebSocket 本身已是低延迟协议,Nginx 的角色是透明透传升级请求并守护长连接,而不是参与通信逻辑。配置不当反而会引入超时断连、握手失败、消息堆积等隐性延迟。
确保 WebSocket 握手一次成功
高实时通信的前提是连接能快速建立且不降级。Nginx 必须显式支持 HTTP/1.1 升级流程:
- proxy_http_version 1.1:强制使用 HTTP/1.1(WebSocket 升级协议强制要求)
-
proxy_set_header Upgrade $http_upgrade:原样转发客户端的
Upgrade: websocket头,否则后端收不到升级意图 -
proxy_set_header Connection "upgrade":告诉后端这不是普通请求,需切换协议;注意值必须是字符串
"upgrade",不能写成$connection_upgrade且未定义 map 映射
禁用默认超时,防止静默断连
WebSocket 连接空闲时没有 HTTP 请求,Nginx 默认的 60 秒 proxy_read_timeout 会主动关闭 TCP 连接,导致“假掉线”。这对心跳间隔较长的实时场景(如物联网设备上报、后台任务通知)尤为致命:
-
proxy_read_timeout 86400(24 小时)或设为
0(不限制),覆盖业务最长空闲周期 - proxy_send_timeout 86400:防止后端响应慢(如批量推送)被 Nginx 中断
- 无需调整
keepalive_timeout——它只影响客户端与 Nginx 之间复用 HTTP 连接,对已升级的 WebSocket 无效
规避中间层干扰,直通帧通信
Nginx 不解析 WebSocket 帧,但某些配置会意外缓冲或重写数据:
- 关闭
proxy_buffering off:避免 Nginx 缓存后端发来的二进制帧,造成不可预测延迟 - 禁用 gzip 压缩(
gzip off):WebSocket 帧是二进制流,gzip 可能破坏帧结构或增加 CPU 开销 - 不设置
proxy_cache相关指令:WebSocket 不适用缓存,启用反而引发异常
验证是否真正生效
光写配置不够,得确认浏览器和后端都走通了:
- 浏览器 Network 面板中,WebSocket 请求状态码必须是 101 Switching Protocols,不是 200 或 502
- 用
curl -i -H "Connection: upgrade" -H "Upgrade: websocket" https://your-domain/ws模拟握手,检查响应头是否含Upgrade: websocket和Connection: upgrade - Nginx error log 出现
upstream prematurely closed connection?说明后端未监听、崩溃或拒绝升级,问题不在 Nginx 配置本身











