keepalive_requests的核心作用是为每个客户端长连接设定请求数上限,达限即断,不等空闲超时;它通过控制复用深度,在“干够活”与“不占位”间平衡,减少无效建连,从而防范握手开销激增和僵尸连接堆积。

keepalive_requests 的核心作用是给每个客户端长连接设一道“请求数上限”,达到即断,不等空闲超时。它不拉长握手,而是通过控制复用深度,让连接在“干够活”和“不占位”之间取得平衡,从而减少无效建连——这才是防范握手开销激增的关键。
它怎么防止连接堆积和握手拉长
连接堆积往往不是因为连接太短,而是因为某些连接“太老又太闲”:用户打开页面后挂机、爬虫慢速复用、前端轮询间隔过长……这些连接长期驻留却几乎不发请求,挤占 worker 进程的连接槽位和内存,导致新用户被迫新建连接,触发大量 TCP 握手与 TLS 协商。
keepalive_requests 从请求维度强制轮换:一个连接处理完 N 次请求后立即关闭,不管它是否还热乎。这相当于把“无限期空闲等待”转化成“有限次活跃服务”,天然规避了僵尸连接堆积。
- 设为 2000,一个 React 页面完整交互(含首屏、路由跳转、API 轮询)基本能复用到底,避免每点一次就重连
- 设为 1000–3000,适合高频 API 场景,让每秒 5–10 次请求的客户端单连接撑够 2–5 分钟,把握手成本摊薄到数百次请求上
- 不设为 0,否则连接永不因请求数关闭,空闲连接会缓慢累积,最终推高 TIME_WAIT 和文件描述符占用
必须配合 keepalive_timeout 才真正生效
keepalive_requests 控制“干多少活”,keepalive_timeout 控制“等多久”。两者是并列退出条件,真实生命周期取二者中先触发的那个。只调大 requests 而不调 timeout,空闲连接仍可能堆积;只压 timeout 而不调 requests,高频客户端又会频繁重建。
- React 静态托管:keepalive_requests 2000 + keepalive_timeout 25s,覆盖活跃交互又防挂机
- API 网关:keepalive_requests 2000 + keepalive_timeout 15s,匹配紧凑请求节奏
- 低频后台:keepalive_requests 500 + keepalive_timeout 45s,侧重连接保有率
别忘了上下游链路要一致
这个参数只管“客户端到 Nginx”这一段。如果 Nginx 同时做反向代理,后端服务收不到复用连接,前面所有优化都白费。
- 确保 upstream 块启用长连接:keepalive 32(连接池大小)
- 转发时声明 HTTP/1.1:proxy_http_version 1.1
- 清除 Connection 头干扰:proxy_set_header Connection ''
- 确认后端服务自身支持 keep-alive(如 Spring Boot 的 server.keepAliveTimeout、Node.js 的 server.timeout)
验证是否真起作用
不能只看配置写没写对,得看连接行为有没有变:
- 用 ss -tnp | grep :80 | grep ESTAB | wc -l 观察活跃连接数是否稳定,而非持续缓慢上升
- 查 Nginx 日志里的 $connection_requests 字段,看多数连接是否在 500+ 请求后才关闭
- 压测时对比:相同 QPS 下,TIME_WAIT 数量是否明显下降,worker_rlimit_nofile 是否远离阈值











