keepalive_timeout的作用是控制连接空闲多久后断开,以平衡复用与释放:设太短增加握手开销,设太长导致资源堆积;需配合keepalive_requests及upstream keepalive协同调优。

keepalive_timeout 的作用不是“减少断开次数”,而是**控制连接空闲多久后才断开**,从而在“复用”和“释放”之间找平衡点。它本身不阻止断开,但设得合理,能让更多请求复用同一连接,自然就减少了新建连接的次数——而新建连接才是 TCP 握手开销的来源。
它怎么影响连接断开行为
这个参数只管“空闲等待期”:一次请求响应结束后,Nginx 会保持连接打开,等客户端下一次请求。如果在 keepalive_timeout 秒内没等到新请求,就主动关闭连接。
- 设太短(比如 2 秒):用户翻页、加载资源稍有延迟,连接就被关了,后续请求只能新建连接 → 握手次数变多
- 设太长(比如 300 秒):大量连接长期空闲占着文件描述符,可能触发 “Too many open files”,反而拖慢整体响应
- 设适中(如 15–30 秒):覆盖常见用户操作间隙(点击按钮、切换标签页),让多个请求有机会走同一条 TCP 连接
必须配合 keepalive_requests 才有效
光靠 timeout 不够。如果一个客户端持续发请求,连接永远不会因空闲超时关闭,但可能被恶意或异常行为长期霸占。
- keepalive_requests 限制单连接最多处理多少次请求(默认 100)
- 达到上限后立即断连,不管是否还在 timeout 时间内
- 这样既防止连接被“锁死”,又保证每个连接都尽量多干活,摊薄握手成本
前端和后端要分开看
keepalive_timeout 只作用于 Nginx 与客户端(浏览器、App)之间的连接。它对后端建连毫无影响。
- 想真正减少后端 TCP 握手,必须在 upstream 块里配 keepalive(如 keepalive 32)
- 同时启用 proxy_http_version 1.1 和 proxy_set_header Connection ''
- 否则前端复用再好,到后端还是每次都要握手
验证是否真的减少了断开
别只改配置,要看效果:
- 用 ss -tnpo | grep :80 | grep ESTAB | wc -l 查当前活跃连接数,对比调优前后变化趋势
- 在 access log 里加 $connection_requests 变量,统计平均单连接请求数,理想值应 ≥ 20(低频)或 ≥ 50(API 场景)
- 抓包看 SYN 包频率:复用率高时,多个 HTTP 请求共享同一个源端口











