nginx代理websocket 60秒断连是因默认proxy_read_timeout=60s所致,需在location块中配置proxy_http_version 1.1、proxy_set_header upgrade/connection、proxy_read_timeout 3600,并关闭buffering与gzip。

WebSocket 在 Nginx 代理下 60 秒自动断开,不是后端或前端代码问题,而是 Nginx 默认的 proxy_read_timeout 60s 主动切断了空闲连接。这个值远低于 WebSocket 实际所需的长连接维持时间,属于典型配置缺失导致的生产故障。
必须加的三项核心配置
这些要写在对应 WebSocket 路径的 location 块内(不能放在 server 或 http 级):
-
启用协议升级支持:添加
proxy_http_version 1.1;,这是 HTTP/1.1 才支持Upgrade机制的基础 -
透传关键请求头:加上
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection "upgrade";,否则后端收不到升级信号,握手失败返回 403 或 200 -
延长读超时时间:显式设置
proxy_read_timeout 3600;(至少 1 小时),该参数控制 Nginx 等待后端数据的时间,空闲连接靠它保活
配套优化项(建议同步开启)
只改超时还不够,还需防止缓冲、压缩、发送中断等干扰因素:
-
关闭响应缓冲:添加
proxy_buffering off;,避免 Nginx 缓存并延迟推送帧,造成粘包或心跳丢失 -
匹配发送超时:设
proxy_send_timeout 3600;,与读超时一致,防止大消息或服务端响应慢被中断 -
禁用 gzip 压缩:加入
gzip off;或确保gzip_types不包含 WebSocket 常用 MIME 类型(如application/json),否则可能破坏帧边界
验证是否生效的三个关键点
重启 Nginx 后,别只看连接“能通”,要确认底层握手和行为完全正确:
- 浏览器 Network 面板检查响应状态码:WebSocket 请求的 Status 必须是 101 Switching Protocols,不是 200、403 或 502
-
查看请求头:确认有
Upgrade: websocket和Connection: Upgrade;响应头中应含Upgrade: websocket和Connection: upgrade -
查 Nginx 错误日志:执行
tail -f /var/log/nginx/error.log,搜索upstream prematurely closed connection,出现即说明后端连接已被提前关闭,配置未生效
前后端协同要点
Nginx 层配置只是基础,稳定依赖两端配合:
-
后端需正确响应 101:例如 Gorilla WebSocket 要调用
conn.SetPingHandler(...)并定期发Ping,否则即使 Nginx 不断连,中间网络设备(如云 LB、NAT 网关)仍可能在 30–90 秒内静默断开 - 前端心跳节奏要激进:若 Nginx 设为 3600s,不代表可完全不发心跳;建议客户端每 25 秒 发一次 ping,服务端必须在 3 秒内 pong 回复,才能穿透最短的中间设备超时阈值
-
HTTPS 下注意协议一致性:wss 请求必须由 HTTPS 的
server块处理,且proxy_pass目标可为 HTTP(内部通信),但务必传X-Forwarded-Proto $scheme,避免后端生成错误的 ws:// 地址











