keepalive_timeout仅控制WebSocket握手阶段的空闲超时,不参与握手后的长连接保活;proxy_read_timeout才负责升级后通信的持续时间,需设为300–600秒并透传Upgrade头,配合应用层心跳实现可靠保活。

keepalive_timeout 不负责 WebSocket 握手后的链路保活,它只管握手前那段时间的空闲连接。真正管长连接持续时间的是 proxy_read_timeout,而 keepalive_timeout 的配置目标,是确保握手阶段不被提前中断。
明确作用边界:它只影响握手阶段
WebSocket 连接分两个阶段:
- 第一阶段是 HTTP 升级握手:客户端发带
Upgrade: websocket和Connection: Upgrade的 GET 请求;Nginx 此时按普通 HTTP 处理,keepalive_timeout控制这个请求响应后、连接尚未升级前的空闲等待时间 - 第二阶段才是真正的 WebSocket 通信:TCP 连接已切换为全双工通道,HTTP 模型失效,此时
keepalive_timeout完全不起作用
keepalive_timeout 的合理取值范围
这个值要略大于后端服务的连接空闲超时,但不能过长:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 推荐设为 5~15 秒,比如 Spring Boot 默认的
server.tomcat.connection-timeout是 60 秒,Nginx 的keepalive_timeout就不该超过它 - 若后端设置了 30 秒超时,Nginx 设成 25 秒更稳妥,避免 Nginx 先断导致 “connection reset by peer” 错误
- 移动端或弱网环境可放宽到 20 秒,但必须同步监控
netstat -an | grep :80 | wc -l和文件描述符使用率,防止连接堆积
真正保活靠 proxy_read_timeout + Upgrade 头透传
WebSocket 长连接不断开,关键在这两项协同:
-
proxy_read_timeout应设为业务静默容忍上限,例如 300~600 秒(5~10 分钟),金融行情类可设 1800 秒 - 必须透传升级意图:
proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection $connection_upgrade; - 务必配合
map指令清除干扰:
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
别忽略 TCP 层和应用层心跳
Nginx 配置只是代理链一环,完整保活还需:
- 操作系统 TCP keepalive 可启用(默认 2 小时太长),但不建议依赖它做实时保活
- 客户端和服务端必须实现应用层心跳(如每 30 秒 ping/pong),这是最可靠的方式
- 防火墙、云负载均衡器等中间设备也有空闲超时(常见 5~30 分钟),需与
proxy_read_timeout对齐










