websocket 在 nginx 代理下超时断开,本质是 nginx 默认按 http 短连接处理(60 秒无数据即关闭),需配置协议升级三要素(proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade")并同步调大 proxy_read_timeout、proxy_send_timeout 和 keepalive_timeout 至一致值(如 86400),同时在 location 块中禁用 proxy_buffering,确保帧实时透传。

WebSocket 在 Nginx 代理下“挂起”或“超时断开”,本质不是连接卡住,而是 Nginx 主动终止了它——默认按 HTTP 短连接逻辑处理,60 秒无数据就关掉。真正要做的,不是“保活”,而是告诉 Nginx:“这不是一次请求,这是一个持续流,请别管它太久没动静。”
必须配齐的协议升级三要素
缺一不可,否则握手失败(返回 200 而非 101),后续所有配置都无效:
- proxy_http_version 1.1; —— 强制使用 HTTP/1.1,Upgrade 机制只在此版本生效;HTTP/1.0 不支持升级,设了也没用
-
proxy_set_header Upgrade $http_upgrade; —— 必须用变量
$http_upgrade,客户端可能发websocket、chat等任意协议名,硬写"websocket"会失败 -
proxy_set_header Connection "upgrade"; —— 注意双引号和小写
upgrade,这是固定字面量,不是变量,也不是$http_connection
超时时间要同步调大且设对地方
只改 proxy_read_timeout 不够,读、写、客户端连接三者都得对齐:
- proxy_read_timeout 86400; —— 控制 Nginx 等待后端推送数据的空闲时长;WebSocket 没响应体,只有帧流,60 秒静默即断;设为 86400(24 小时)是稳妥值,但至少 ≥ 后端心跳间隔 × 2
- proxy_send_timeout 86400; —— 控制 Nginx 往客户端发送数据时的连续等待时间;大消息分片、网络延迟都可能触发此超时,必须与 read 值一致
- keepalive_timeout 86400; —— 保持客户端到 Nginx 的 TCP 连接存活;虽不影响上游,但与前后端超时对齐可减少边缘抖动
⚠️ 全部必须放在 location 块内(如 location /ws/ { ... }),全局或 server 块中设置不生效。
禁用缓冲,让帧实时透传
WebSocket 是帧流,不是完整响应;Nginx 默认开启缓冲(proxy_buffering on),会导致消息堆积、延迟、甚至粘包:
- proxy_buffering off; —— 强制关闭缓冲,必须显式声明;默认是 on,不写就等于开着
- 禁用后,
proxy_buffer_size、proxy_buffers等参数失效,无需再配 - 可选加
proxy_cache off;防止缓存干扰实时性
HTTPS 和路径匹配的硬性要求
wss 连接失败,常因链路不完整或路径被重写:
- SSL 配置需完整:含有效证书、密钥、
ssl_protocols TLSv1.2 TLSv1.3;HTTP/2 必须禁用(http_v2 off),因不支持 Upgrade -
location必须精确或前缀匹配 WebSocket 路径(如location /ws/ { ... }),避免rewrite改写请求头或路径,否则 Upgrade 头可能丢失 - 若用 upstream,建议加
keepalive 32;并配合ip_hash或 sticky session,确保同一连接始终打到同一台后端











