TCP keepalive是被动探测空闲连接是否失效的机制,非“保活开关”;默认2小时后发首探针,间隔75秒、重试9次,易被NAT等中间设备提前断开;应调优tcp_keepalive_time(如600秒)、intvl(如30秒)、probes(如3次),并区分系统级与应用层配置,且须与应用层心跳协同使用。

TCP keepalive 不是“让连接一直活着”的开关,而是被动探测空闲连接是否已失效的机制。它只在连接无数据收发时启动,靠发探测包(通常是空ACK)判断对端是否响应。默认配置下,要等2小时才发第一个包,之后再耗11分钟才能断连——这在现代网络中早已过时,尤其面对NAT、云负载均衡或防火墙时,连接常在探测前就被中间设备清掉了。
三个核心参数各管什么
keepalive行为由三个整数参数协同控制,单位统一为秒或次数:
- tcp_keepalive_time:连接空闲多久后发第一个探测包。默认7200(2小时),但家用路由器NAT表一般5–30分钟就超时,设600(10分钟)更实际
- tcp_keepalive_intvl:两次探测之间的间隔。默认75秒,公网链路易抖动,压到20–40秒能更快确认异常
- tcp_keepalive_probes:连续无响应后断连的探测次数。默认9次,总超时过长;设3次即可,从首次探测到关闭连接约耗时“idle + (probes−1)×intvl”
系统级配置:适合统一策略场景
全局修改影响所有启用SO_KEEPALIVE的连接,适合只跑一类长连接服务的网关或嵌入式设备:
- 临时生效(重启失效):sudo sysctl -w net.ipv4.tcp_keepalive_time=600、sudo sysctl -w net.ipv4.tcp_keepalive_intvl=30、sudo sysctl -w net.ipv4.tcp_keepalive_probes=3
- 永久生效:在/etc/sysctl.conf末尾追加三行,再运行sudo sysctl -p
- 注意:仅改sysctl不启用SO_KEEPALIVE选项,socket仍不会发探测包
应用层配置:关键连接必须单独设
高并发服务(如Netty、Nginx、自研代理)应优先在代码中为每个socket定制参数,避免一刀切影响短连接或监控探针:
- 先启用保活:setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable))
- 再设置TCP层参数(Linux 2.4+支持):setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))、setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval))、setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &probes, sizeof(probes))
- 务必检查返回值:旧内核或musl libc(如Alpine)可能不支持,返回ENOPROTOOPT需降级处理
别混淆:keepalive不是应用层心跳
TCP keepalive是传输层机制,只检测“对端TCP栈是否在线”,无法发现应用崩溃、进程卡死或HTTP服务无响应。它和HTTP Keep-Alive(复用连接)、MQTT的PINGREQ/PINGRESP、WebSocket的ping/pong完全无关。真实业务中,建议二者共存:keepalive兜底防半开连接,应用层心跳做业务健康检查。



















