nginx 不生成心跳,仅需透传 ping/pong 帧并防止断连:必须配置 proxy_http_version 1.1、透传 upgrade 和 connection 头;proxy_read_timeout 等超时设为 86400;proxy_buffering off;精确 location 匹配并启用 ip_hash 或状态共享。

Nginx 本身不“开启”心跳,也不生成或响应 ping/pong 帧。它只是必须透传心跳、不干扰连接、不提前断连——这才是 WebSocket 长连接保活的关键。
要让 Nginx 正确配合前后端的心跳机制,需从协议升级、超时控制、缓冲行为、路径匹配四方面精准配置。
必须透传 WebSocket 升级头,握手才能成功
WebSocket 握手是一次 HTTP/1.1 升级请求,Nginx 若过滤或改写关键头部,后端收不到信号,就会返回 200 而非 101,连接直接失败:
-
proxy_http_version 1.1;—— 缺了这句,Nginx 默认用 HTTP/1.0,无法支持 Upgrade -
proxy_set_header Upgrade $http_upgrade;—— 用变量转发原始值(如websocket、mqtt),不能硬写"websocket" -
proxy_set_header Connection "upgrade";—— 必须是带英文双引号的字面量"upgrade",不能用$http_connection(它常含keep-alive,会覆盖升级意图)
超时时间必须远大于心跳间隔,并留出余量
Nginx 默认 proxy_read_timeout 60 秒:只要后端 60 秒没向客户端发数据,它就主动断连。这不是故障,是默认资源策略。
若你的心跳每 30 秒一次,proxy_read_timeout 至少设为 90 秒以上才安全;生产环境推荐统一设为 86400(24 小时):
-
proxy_read_timeout 86400;—— 控制 Nginx 等待后端数据的最大时间 -
proxy_send_timeout 86400;—— 防止后端发送大消息或广播帧时被中断 -
keepalive_timeout 86400;—— 保持客户端到 Nginx 的 TCP 连接存活,与上游对齐更稳妥
⚠️ 注意:心跳间隔建议避开 60 秒整数倍(如设为 25s、45s 或 55s),避免周期性误判断连。
关闭缓冲与缓存,防止帧流被破坏
WebSocket 数据以帧(TEXT/BINARY/PING/PONG)为单位实时双向流动,Nginx 默认行为会合并、延迟甚至截断帧:
-
proxy_buffering off;—— 必须放在location块内,禁用响应缓冲,防粘包 -
proxy_cache off;—— 显式禁用缓存,否则 Upgrade 请求可能被缓存命中返回 200 -
tcp_nodelay on;—— 绕过 Nagle 算法,小帧(如光标移动、VAD 触发)立即送达 -
gzip off;—— 或确保gzip_types不包含 WebSocket 相关类型(如text/event-stream)
确保请求进入正确 location,且后端状态不漂移
WebSocket 连接状态通常存在内存中,若负载均衡轮询打到不同后端节点,连接即丢失、报错 1006:
- 使用精确路径匹配,例如
location /ws/ { ... },避免用location / {}兜底 - 若部署多实例,需启用会话保持(如
ip_hash)或改用外部状态存储(Redis + sticky session) - 检查
proxy_pass是否指向正确的后端地址和端口,避免 rewrite 或 header 改写干扰路径
不复杂但容易忽略











