nginx代理websocket必须正确配置协议升级、超时参数、缓冲与会话保持及https支持:①proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade"三者缺一不可;②proxy_read_timeout等超时值需匹配心跳间隔;③proxy_buffering必须设为off;④wss需确保ssl终止正确且upgrade头未被过滤。

Nginx 代理 WebSocket 不是简单加几行就能跑通,必须显式绕过它对 HTTP 短连接的默认假设。配置错一个关键项,就会握手失败、60 秒断连、心跳被截断——这些不是偶然,而是必然结果。
核心协议升级配置必须齐全
WebSocket 握手本质是一次带特殊头的 HTTP/1.1 请求,Nginx 必须完整透传升级信号:
- proxy_http_version 1.1:强制使用 HTTP/1.1(HTTP/1.0 不支持 Upgrade 机制)
- proxy_set_header Upgrade $http_upgrade:用变量传递,不能硬写 "websocket"(客户端可能发 chat、mqtt 等其他协议)
- proxy_set_header Connection "upgrade":固定字符串 "upgrade",不是 $http_connection(Connection 是逐跳头,不可继承)
三者缺一不可。漏掉任一,后端收不到 Upgrade 信号,返回 200 而非 101,连接直接失败。
超时参数不是可选优化,而是保命设置
WebSocket 是空闲仍活跃的长连接,Nginx 默认 proxy_read_timeout=60 秒就是定时炸弹:
- proxy_read_timeout:控制 Nginx 等待后端数据的最大空闲时间,必须 ≥ 后端心跳最大间隔(如后端 ping/pong 每 30 秒一次,建议设为 60 或以上)
- proxy_send_timeout:同步设大,否则服务端发大消息或延迟响应时会被掐断
- keepalive_timeout:保持客户端与 Nginx 之间 keep-alive 连接的时长,也需匹配心跳节奏
别设 0——Nginx 不支持该值,会回退到默认 60;必须填正整数,常见设为 86400(24 小时)。
缓冲与会话保持要按需关闭和选择
WebSocket 数据是帧流,不是完整响应体:
- proxy_buffering off:必须显式关闭(默认是 on),否则 Nginx 缓存帧导致前端收不到实时消息、粘包或重连
-
会话保持策略要匹配部署场景:
- ip_hash:适合公网 IP 分散用户,但局域网易扎堆,宕机不自动迁移
- sticky cookie(需 Plus 或第三方模块):支持故障转移,适合 Web 页面内嵌 WS 场景
- 不强绑定 + 后端共享状态:用加权轮询,后端通过 Redis 统一管理连接映射
HTTPS 下 WSS 连接失败的典型原因
浏览器要求 wss:// 全链路可信,Nginx 终止 SSL 后代理明文 ws 到后端,但必须满足:
- SSL 配置完整:ssl_certificate 和 ssl_certificate_key 路径正确,且证书有效
- 返回的 101 响应必须来自 HTTPS 上下文:确保 server 块 listen 443 ssl,并启用 http2(可选但推荐)
- location 块中 proxy_pass 目标地址为 http://(不是 https://),WSS 升级只发生在客户端→Nginx 加密链路,Nginx→后端走明文 ws
若卡在连接建立阶段,优先检查 SSL 配置是否生效、证书是否被浏览器信任、以及 Upgrade 头是否被防火墙或中间设备过滤。











