优化nginx keepalive的核心是匹配业务节奏:keepalive_timeout控制空闲等待时长(非总寿命),静态资源设30–45秒、移动端api设15–30秒、高并发网关压至5–10秒并启用reset_timedout_connection on;keepalive_requests限制单连接请求数,与timeout构成双保险;必须协同upstream keepalive、全链路超时对齐及运行指标验证。

优化 Nginx 的 keepalive 参数,核心不是“设一个固定值”,而是让连接生命周期匹配真实业务节奏:既避免频繁建连拖慢吞吐,又防止空闲连接长期驻留吃光内存和文件描述符。
分场景设 keepalive_timeout:它管的是“等多久”,不是“活多长”
这个参数控制 Nginx 发完响应后,愿意为下一个请求空闲等待的最长时间。有新请求就重置计时器,超时无动静就断开。关键点在于“空闲”二字——它不干预正在传输的请求,也不决定 TLS 或整个会话寿命。
- 静态资源服务(JS/CSS/图片/CDN):用户加载密集、间隔短,设 30–45 秒 较稳妥,覆盖首屏+后续资源拉取周期
- 移动端 API 或微服务调用:网络不稳定、客户端保活策略各异,中间设备(如 WAF、NAT)易静默断连,推荐 15–30 秒
-
高并发低延迟网关(如实时消息、推送):连接需快速周转,防堆积,可压到 5–10 秒,并启用
reset_timedout_connection on直接发 RST 回收 - 内网后台系统或 SSE 长轮询:若确认客户端真会持续复用(比如每 30 秒发一次心跳),可设 60–300 秒,但必须验证,否则只是制造僵尸连接
配合理设 keepalive_requests:它管的是“干多少活”,不是“歇多久”
该参数限制单个连接最多处理多少次请求后强制关闭,与超时无关,是独立的退出条件。它和 keepalive_timeout 共同决定连接实际生命周期——谁先触发,谁生效。
- React/Vue 单页应用:首屏加载 + 交互 + 轮询常达数十请求,建议设 2000
- 高频轻量 API(如心跳、状态查询):QPS 高、响应快,设 1000–3000;若后端偶发延迟,可降至 200–500 强制轮转,防卡死
- 低频管理后台或内网接口:用户操作稀疏,设 200–500 更省资源,避免连接空转
- WebSocket 或 SSE 升级前握手阶段:这类连接不走常规 HTTP 请求流,keepalive_requests 影响极小,保持默认 100 即可
必须同步启用的三项配套机制
只调 keepalive_timeout 和 keepalive_requests 效果有限,以下配置缺一不可:
-
upstream keepalive 连接池:在 upstream 块中加
keepalive 32;(数值按后端实例数×2~4 设置),并确保proxy_http_version 1.1;和proxy_set_header Connection '';同时存在,否则后端连接仍为短连接 - reset_timedout_connection on:启用后,超时连接直接发 RST 而非 FIN,跳过 TIME_WAIT,内核立刻回收 socket,对弱网残留或慢速攻击特别有效
-
全链路超时对齐:Nginx 的
keepalive_timeout 30 25中第二个值(25)要略小于第一个值(30),且必须 ≤ 后端服务的连接超时(如 Tomcat 的connectionTimeout);中间若有云 LB 或 WAF,其空闲超时也须 ≥ Nginx 值,否则连接会在半路被掐断
用指标验证是否真起作用,而不是改完就以为好了
配置写对只是第一步,要看运行态数据才能判断是否调准:
- 用
ss -tn | grep :443 | grep ESTAB | wc -l观察 ESTABLISHED 连接数趋势:调低 timeout 后应明显回落,不再持续攀升 - 查
nginx stub_status中的 Waiting 状态数:持续偏高说明空闲连接堆积,timeout 可能设太长 - 开启日志变量
$connection_requests,统计单连接平均承载请求数:若远低于 keepalive_requests 设定值,说明复用率低,可能因客户端不支持或中间设备干扰 - 检查 error log 是否频繁出现
upstream prematurely closed connection或Connection reset by peer:大概率是上下游 timeout 错位,而非 Nginx 自身问题











