keepalive_timeout本身不直接降低tcp握手开销,而是通过控制nginx与客户端空闲连接存活时长(5–60秒)为复用创造条件;设太短致频繁重连,太长则耗尽文件描述符;需配合keepalive_requests及客户端、tls会话复用协同生效。

keepalive_timeout 本身不直接降低 TCP 握手开销,但它决定了客户端与 Nginx 之间空闲连接能保留多久——只有连接没被关掉,后续请求才能复用它,从而跳过新建连接所需的三次握手。它的作用是“创造复用条件”,而非执行复用动作。
只管前端连接,不管后端建连
这个参数仅作用于 Nginx 与客户端(浏览器、App、CDN)之间的连接,对 Nginx 到后端服务的 TCP 握手完全无效。后端建连开销靠的是 upstream 块里的 keepalive 指令,两者必须分开配置、协同生效。
- 设太短(如 2 秒):用户连续点击或加载资源时连接已断,被迫重建,握手次数反而上升
- 设太长(如 300 秒):大量空闲连接堆积,耗尽 worker 进程的文件描述符,可能触发 Too many open files 错误
- 合理区间是 5–60 秒,具体取决于业务节奏:API 网关建议 15–30 秒,静态资源可设 30–45 秒,内网低频系统可放宽至 60 秒
必须配合 keepalive_requests 才能稳定复用
即使连接没超时,也不能让它无限处理请求。keepalive_requests 控制单个连接最多服务多少次请求后强制关闭,防止异常客户端长期霸占连接。
- 默认值 100 偏保守,适合通用 Web 场景
- 高频小请求(如心跳、轮询)可调高至 500–1000
- 若 keepalive_timeout 设为 30 秒但 keepalive_requests 是 100,而实际每秒只来 1 个请求,那连接可能 100 秒后才断——此时 timeout 就形同虚设
复用的前提是两端都支持 Keep-Alive
Nginx 单方面延长 timeout 没用。如果客户端没发 Connection: keep-alive,或者中间有负载均衡器/CDN 截断了该头,连接仍是短连接。
- 用 curl -v 访问接口,检查响应头是否含 Connection: keep-alive
- 确认客户端 SDK(如 OkHttp、requests)未显式设置 Connection: close
- 检查上游链路(如 AWS ALB、Cloudflare)是否覆盖或禁用了 Keep-Alive
HTTPS 下要和 TLS 会话复用协同
TCP 复用只是第一步。HTTPS 中,即使连接复用成功,若 TLS 会话已失效,仍需完整握手(含证书校验)。这时 keepalive_timeout 设得再长也没法省 CPU。
- 必须启用 ssl_session_cache shared:SSL:10m 和 ssl_session_timeout 4h
- keepalive_timeout 建议设为 30 秒左右,略短于 ssl_session_timeout,确保连接复用期内 TLS 会话大概率有效
- 避免在 WAF 或 CDN 层禁用 session ticket,否则 TLS 复用率会大幅下降











