nginx代理websocket频繁断开主因是默认按http短连接处理,需在location块中配置proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade",并调大超时、禁用缓冲与gzip。

Linux 下 Nginx 代理 WebSocket 频繁断开,90% 以上不是后端或网络问题,而是 Nginx 把长连接当普通 HTTP 请求处理了——它默认丢 Upgrade 头、60 秒空闲就切断、还缓存帧数据。解决的核心是让 Nginx 明白:这不是一次请求,而是一条要活很久的双向通道。
必须加在 location 块里的三项基础配置
这三行不能写在 http 或 server 块顶层,必须精准落在匹配 WebSocket 路径(如 /ws/、/socket)的 location 块内:
-
启用 HTTP/1.1 协议:添加
proxy_http_version 1.1;—— HTTP/1.0 不支持 Upgrade 机制,缺了这一行握手直接失败 -
透传 Upgrade 头:添加
proxy_set_header Upgrade $http_upgrade;—— 用变量确保兼容 WebSocket/MQTT/STOMP 等不同客户端 -
声明升级意图:添加
proxy_set_header Connection "upgrade";—— 引号不能少,值必须是字面量 "upgrade",写成$http_connection或keep-alive都会失效
延长超时并关闭干扰行为
只配头还不够,Nginx 默认策略会主动破坏长连接:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
-
调大读超时:设
proxy_read_timeout 86400;(24 小时),至少 ≥ 后端心跳间隔 × 3;默认 60 秒是高频断连主因 -
同步发送超时:加
proxy_send_timeout 86400;,避免大消息分片发送中途被中断 -
禁用响应缓冲:加
proxy_buffering off;—— 否则后端推送的多帧可能被攒包,导致粘包或 pong 延迟 -
关掉 gzip 压缩:加
gzip off;或确保gzip_types不含application/json、text/plain—— 压缩会破坏 WebSocket 帧边界
路径、SSL 和验证要点
配置写对了,但位置或环境不匹配,依然无效:
-
路径严格一致:前端连
wss://a.com/ws,Nginx 的location必须是/ws(或/ws/),proxy_pass地址也需带相同路径,避免隐式重写导致 404 或降级 -
WSS 必须走 HTTPS:server 块中要有
listen 443 ssl;,且配置有效证书、密钥和ssl_protocols TLSv1.2 TLSv1.3; -
验证是否真生效:浏览器 Network 面板中 WebSocket 请求响应状态码必须是 101 Switching Protocols,响应头必须同时含
Upgrade: websocket和Connection: upgrade
辅助诊断与客户端协同
代理配置是基础,客户端也要配合防系统冻结或 NAT 超时:
- 用
curl -i -k -H "Connection: upgrade" -H "Upgrade: websocket" https://your-domain/ws/模拟握手,观察返回头 - 查 Nginx 错误日志,搜索
upstream prematurely closed connection或client closed connection,有则说明仍有透传或超时问题 - 前端心跳间隔建议 ≤25 秒,服务端超时设为 ≥60 秒;iOS/Safari 切后台会冻结定时器,需监听
document.visibilityState动态控制心跳










