websocket 在反向代理环境下易断连,根本原因是 nginx 默认不支持其长连接升级机制;需显式配置 upgrade 和 connection 头透传、延长 proxy_read_timeout 等超时参数,并验证 101 响应及请求头。

WebSocket 在反向代理环境下容易断连,根本原因是 Nginx 默认不支持 WebSocket 的长连接升级机制。要让 WebSocket 正常穿透 Nginx,必须显式配置协议升级头和连接保活参数。
必须设置的 WebSocket 升级头
Nginx 默认不会转发 Connection 和 Upgrade 请求头,而 WebSocket 握手依赖这两个字段。需在 location 块中明确透传:
-
proxy_set_header Upgrade $http_upgrade;—— 将客户端发起的Upgrade: websocket透传给后端 -
proxy_set_header Connection "upgrade";—— 强制将连接升级为 WebSocket 模式(注意:值用双引号包裹,避免被解析为变量) - 这两行不能遗漏,否则后端收不到升级信号,始终按 HTTP 处理,握手失败
保持长连接不超时
WebSocket 是长连接,但 Nginx 默认的超时时间(如 proxy_read_timeout 默认 60 秒)会主动关闭空闲连接,导致断连:
- 建议设为较大值,例如
proxy_read_timeout 86400;(24 小时),或根据业务场景设为数小时 - 同时配
proxy_send_timeout 86400;,防止服务端响应延迟触发中断 - 若使用负载均衡,还需检查 upstream 的
keepalive连接池配置,避免复用旧连接引发状态错乱
验证是否生效的关键点
配置完别急着重启,先确认三件事:
- 用浏览器开发者工具查看 WebSocket 请求的请求头,确认含
Upgrade: websocket和Connection: upgrade - 检查响应状态码是否为
101 Switching Protocols,不是 200 或 502 - Nginx 错误日志(
error.log)中不应出现"upstream prematurely closed connection"或"client closed connection"类报错
常见陷阱与绕过方案
有些框架(如某些 Spring Boot 版本)在反代后无法正确识别 X-Forwarded-Proto,导致 WebSocket URL 生成为 http:// 而非 wss://:
- 前端初始化时,手动判断协议:
const ws = new WebSocket(location.origin.replace(/^http/, 'ws')); - 后端启用信任代理头(如 Spring Boot 配置
server.forward-headers-strategy=framework),并设 Nginx 传X-Forwarded-Proto $scheme - 若仍不稳定,可临时加
proxy_http_version 1.1;(虽默认已是 1.1,但显式声明更稳妥)
不复杂但容易忽略,核心就三点:透传升级头、延长超时、验证握手响应。配对了,WebSocket 就能稳稳跑在 Nginx 后面。










