心跳检测依赖TCP Keepalive机制,由内核自动执行,核心参数为tcp_keepalive_time、tcp_keepalive_intvl和tcp_keepalive_probes,三者共同决定连接失效总时长;不同场景需差异化配置,且须两端同时启用并规避中间设备超时限制。

心跳检测靠的是 TCP Keepalive 机制,不是应用层自己发 ping 包。它由内核自动完成,关键在于三个参数的协同设置:空闲多久开始探、每次探隔多久、最多探几次。
理解三个核心参数的实际含义
这三个值共同决定连接从“静默”到“被判定死亡”的总耗时:
- tcp_keepalive_time:连接完全没数据收发后,等待多久才发第一个探测包。默认 7200 秒(2 小时),对生产环境过长;
- tcp_keepalive_intvl:第一次探测没回音后,每隔多久再发一次。默认 75 秒;
- tcp_keepalive_probes:连续多少次探测无响应,就彻底关闭连接。默认 9 次。
总失效时间 ≈ time + intvl × probes。比如设为 600 + 30 × 3 = 690 秒(11.5 分钟),比默认的近 2.2 小时快得多。
按场景推荐配置值
不同业务对“连接存活”的敏感度不同,不能一刀切:
- 物联网设备或移动客户端:网络易中断、切换频繁。建议 time=300(5 分钟)、intvl=10、probes=3,总检测窗口约 330 秒,快速识别假在线;
- 微服务网关或长连接 WebSocket/SSE:需兼顾稳定性与及时性。推荐 time=600(10 分钟)、intvl=30、probes=3;
- 数据库连接池:避免用到已断开的连接句柄。建议 time=900(15 分钟)、intvl=45、probes=3,平衡探测开销与连接有效性;
-
SSH 或管理通道:可单独通过
sshd_config配置TCPKeepAlive yes+ClientAliveInterval,更贴近运维习惯。
两种主流配置方式
全局生效适合统一策略,单 socket 级别更灵活精准:
-
系统级(影响所有启用 keepalive 的连接):
编辑/etc/sysctl.conf追加三行:net.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3
执行sudo sysctl -p生效; -
应用层(C/Python/Java 等):
创建 socket 后先启用SO_KEEPALIVE,再用平台支持的扩展选项定制参数(Linux 3.7+ 支持):setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl));setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));
必须避开的常见误区
- 只改
SO_KEEPALIVE开关却不调参数——仍走内核默认 2 小时,等于没优化; - 把
time设得太小(如 30 秒),在低频上报类业务中会徒增无效探测流量; - 忽略中间设备(NAT/防火墙)的 conntrack 超时(常为 2–5 分钟),导致即使 keepalive 发了包,连接仍被网关静默剔除;此时
time必须小于该阈值,否则探测毫无意义; - 未在服务端和客户端两端同时启用——keepalive 是双向探测,单边开启无法防止半开连接泄漏。










