keepalive_timeout在超长连接场景中作用是防止空闲连接被误杀,而非维持活跃通信:它仅控制无新请求时的等待时长,需设为高于心跳间隔(如45–60秒)并协同proxy_read_timeout配置,避免因静默超时导致断连。

在超长连接场景(如 WebSocket、SSE、长轮询、实时流推送)中,keepalive_timeout 的作用不是“延长连接寿命”,而是防止它被误杀——关键在于把它设得足够长、且与上下游行为对齐,同时避免空闲连接无限制堆积。
明确它的角色:只管“空闲”,不管“忙碌”
keepalive_timeout 控制的是客户端与 Nginx 之间连接在无新请求到达时的最长等待时间。一旦有请求进来,计时器就重置;而正在传输响应(比如后端还在发 WebSocket 消息)时,它完全不参与判断。
所以,在超长连接中,它不负责维持活跃通信,而是兜底防断连——确保心跳或间歇性数据不会因“静默”被关掉。
- WebSocket 场景下,客户端每 30 秒发一次 ping,那
keepalive_timeout至少设为 45–60 秒,留出缓冲 - SSE 流式响应期间,即使后端持续写入,只要客户端没发新请求,Nginx 仍会按此值倒计时——因此必须设高(如
keepalive_timeout 86400) - 若设得太短(如默认 65 秒),心跳间隔稍一波动,连接就被 Nginx 主动 FIN 关闭,前端报
WebSocket is closed before the connection is established或反复重连
必须配合 proxy_read_timeout 使用
keepalive_timeout 管前端空闲,proxy_read_timeout 才管后端响应延迟。两者常被混淆,但在超长连接中必须协同:
-
proxy_read_timeout决定 Nginx 等待后端返回数据的最长时间(例如后端推送消息前要等 5 分钟,那就得设为300或更高) - 该值应 ≤
keepalive_timeout,否则可能出现:后端还在传数据,Nginx 却因空闲超时先关了客户端连接,导致 502 错误 - 典型配置:
keepalive_timeout 86400;+proxy_read_timeout 86400;(24 小时),再配合后端心跳机制
注意响应头与客户端实际行为的对齐
Nginx 可通过双参数语法向客户端传递建议:keepalive_timeout 86400 86300;,其中第二个值会写入 Keep-Alive: timeout=86300 响应头。部分老客户端或 SDK(如某些 OkHttp 版本)会读取这个值并据此管理自身连接池。
但现代浏览器和主流 HTTP 库大多忽略该头,依赖自身策略。因此更可靠的做法是:
- 在客户端 SDK 中显式设置最大空闲时间(如 Axios 不控制 keep-alive,但 OkHttp 的
idleConnectionTimeout需设为略小于 Nginx 的keepalive_timeout) - 确认 CDN 或负载均衡器(如 AWS ALB、腾讯云 CLB)未覆盖或提前中断连接——它们的 keep-alive 超时必须 ≥ Nginx 值
防资源堆积:不能只靠 timeout,还要限请求数和监控
设成 24 小时不等于放任不管。超长连接若无约束,可能因异常客户端或后端卡死长期滞留,耗尽 worker_connections 或文件描述符。
- 搭配
keepalive_requests 1000;:单个连接最多处理 1000 次请求(对长轮询可能一生只用 1–2 次,但对高频 SSE 推送有意义),避免无限复用 - 启用
stub_status并定期查Active connections和Reading/Writing/Waiting分布,Waiting 过高说明大量连接挂起,需结合ss -s | grep "TCP:"观察 TIME_WAIT 是否突增 - 系统层同步调优:
net.ipv4.tcp_fin_timeout = 30加快端口回收,net.ipv4.tcp_tw_reuse = 1允许复用 TIME_WAIT 连接



















