nginx的keepalive配置与linux内核tcp keepalive机制本质不同:前者是http层连接复用控制(如keepalive_timeout、upstream keepalive),由nginx主动管理生命周期以减少握手开销;后者是内核对空闲tcp连接的被动健康探测(tcp_keepalive_time/intvl/probes),仅兜底防僵死,不参与复用逻辑,二者需协同调优才能支撑百万级稳定并发。

很多人混淆 Nginx 的 keepalive 配置和 Linux 内核的 TCP Keepalive 探测机制,其实它们作用对象、触发时机和调优目标完全不同。前者是 HTTP 层连接复用控制,后者是内核网络栈对空闲 TCP 连接的健康探测。搞清区别再调,才能避免“越调越卡”。
HTTP keepalive(Nginx 主动管理)
这是 Nginx 为客户端提供的长连接能力,核心是复用单个 TCP 连接收发多个 HTTP 请求,省去重复握手开销。它不依赖内核 TCP Keepalive,完全由 Nginx 自己控制生命周期:
- keepalive_timeout:连接空闲多久后关闭,默认 75s。建议设为 60s,兼顾复用率与资源释放速度;API 类服务可缩至 15–30s
- keepalive_requests:单连接最多处理多少请求,默认 100。必须设高(如 10000),否则连接在未超时前就因请求数满被强制断开,导致“假短连接”
-
upstream keepalive:反向代理场景下,Nginx 与后端之间的连接池也要配,例如:
upstream backend {<br> server 10.0.1.10:8080;<br> keepalive 200;<br>}
其中200是每个 worker 保留在连接池中的空闲连接数,不是总连接上限
TCP Keepalive Probes(内核被动探测)
这是 Linux 内核对已建立但长期无数据传输的 TCP 连接,自动发送探测包确认对方是否存活。它不影响 HTTP 复用逻辑,只在连接“静默太久”时起兜底作用,防止僵死连接堆积:
- tcp_keepalive_time:连接空闲多久后开始发第一个探测包,默认 7200 秒(2 小时)。高并发场景建议调低至 1800(30 分钟)或 1200(20 分钟)
- tcp_keepalive_intvl:两次探测之间间隔,默认 75 秒。建议设为 30 秒,加快失败识别
- tcp_keepalive_probes:连续失败几次后判定连接死亡,默认 9 次。建议设为 5,避免等待过久才释放资源
- 这些参数只影响内核行为,Nginx 不感知也不干预;即使你关掉它们,Nginx 的 HTTP keepalive 仍照常工作
为什么两者要协同调?
单独调某一层容易出问题:
- HTTP keepalive_timeout 设太长(如 300s),但内核 tcp_keepalive_time 还是默认 2 小时 → 连接实际没死,却长期占着 worker_connections,挤占新连接资源
- 反向代理中,Nginx 到后端的连接若未配 upstream keepalive,每次请求都新建 TCP 连接 → 即使内核 Keepalive 开了也救不了握手风暴
- 客户端是移动设备或 NAT 网关后,中间设备可能主动 kill 掉空闲连接(如 5 分钟),此时 Nginx 的 keepalive_timeout 若设为 60s,但没配 client_header_timeout/send_timeout,仍可能在读写阶段卡住
配套必须做的几件事
光调 keepalive 相关参数远远不够,下面这些是真正让百万连接稳住的基础:
- 内核
somaxconn和 Nginxlisten backlog必须对齐(都设为 65535 或更高),否则新连接进不来 - 确保
ulimit -n≥ 65535,并在 nginx.conf 中用worker_rlimit_nofile同步生效 - 禁用
tcp_tw_recycle(已废弃且在 NAT 环境下引发乱序),仅启用tcp_tw_reuse = 1 - 对于 SSE、WebSocket 等流式长连接,必须关闭
proxy_buffering和gzip,否则数据被攒着不发











