TCP保活机制是Linux内核提供的被动链路检测手段,需显式启用SO_KEEPALIVE;默认空闲7200秒后发首探,间隔75秒、最多9次无响应则断连;探测包为len=0、seq=ack-1的特殊ACK,可单连接定制参数,但无法替代应用层心跳。

Linux 内核对 TCP 连接的保活探测机制,本质是一种被动、定时的链路存活检测手段,不依赖应用层数据,只在连接空闲时启动。
保活触发条件与默认行为
该机制默认关闭,需应用通过 SO_KEEPALIVE 套接字选项显式启用。启用后,内核按三个全局参数控制探测节奏:
- tcp_keepalive_time:连接空闲满 7200 秒(2 小时)后,发送第一个探测包
- tcp_keepalive_intvl:后续每次探测间隔 75 秒
- tcp_keepalive_probes:最多发 9 次,全部无响应则通知应用层断连
也就是说,一个默认配置的空闲连接,最快也要约 2 小时 11 分钟才会被判定失效。
探测报文的实际形态
Keepalive 探测不是普通数据包,而是特殊构造的 TCP 段:
- 不携带应用层数据(len = 0)
- 序列号设为 ack - 1,即“重传上一个确认序号前一位”,属于合法但无负载的 ACK 类型报文
- 目的不是传输数据,而是触发对端协议栈回应 —— 正常时返回 ACK;若对端进程已退出但 socket 未关闭,可能回 RST;完全无响应则进入超时重试
单连接可定制参数
全局参数影响所有启用保活的连接,但可通过 TCP 层 socket 选项为单个连接单独设置:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- TCP_KEEPIDLE:等效于 tcp_keepalive_time,单位秒
- TCP_KEEPINTVL:等效于 tcp_keepalive_intvl,单位秒
- TCP_KEEPCNT:等效于 tcp_keepalive_probes,整数次
调用 setsockopt(fd, IPPROTO_TCP, ...) 即可覆盖系统默认值,适合对延迟敏感或连接生命周期差异大的服务。
适用场景与关键局限
保活机制适合解决以下问题:
- 中间设备(如 NAT 网关、云负载均衡)因空闲超时静默断连
- 对端主机宕机或进程崩溃导致的半开连接堆积
- 数据库连接池、长连接网关等需及时释放无效 fd 的场景
但它无法解决:
- 对端进程卡死但 socket 仍打开(无 RST/ACK,探测包照常响应)
- 四层代理或 eBPF 转发路径丢弃探测包
- 应用逻辑层“假活跃”(有数据收发,但业务已停滞)
因此生产环境必须搭配应用层心跳(如自定义 PING/PONG、gRPC keepalive、Redis PING),两者互补而非替代。










