Keep-Alive 是什么
TCP Keep-Alive 在连接空闲一段时间后,由一端发出不携带数据的探测包,确认对端是否仍然存在。它默认是关闭的,需要应用显式打开套接字选项才会生效。抓包上的表现是长时间空闲之后突然出现周期性的小包,间隔与次数由内核参数决定。
基本信息
| 用途 | 探测空闲连接的对端是否仍然存在 |
|---|---|
| 启用方式 | 应用设置 SO_KEEPALIVE,默认关闭 |
| 内核参数 | net.ipv4.tcp_keepalive_time / intvl / probes(Linux) |
| 抓包表现 | 空闲后周期性出现零载荷小包 |
| 查看命令 | ss -tanp 查看连接状态,配合 -o 可看定时器信息 |
典型使用场景
- 长连接业务空闲后首个请求失败,判断是否为连接已被回收
- 核对保活间隔与中间设备会话老化时间是否匹配
- 解释抓包里空闲后出现的小包,避免误当成心跳协议
- 评估是否需要改用应用层心跳以获得更短的检测周期
- 排查服务重启后旧连接为何长时间不释放
常用命令
常用命令
sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes # 查看保活参数
ss -tanp | head # 查看连接状态与进程
ss -tanpo | grep -i keep # 查看定时器信息(字段随版本)信号与含义
| 信号 | 含义 | 说明 |
|---|---|---|
| 空闲后出现小包 | 保活探测开始 | 空闲时长等于 keepalive_time |
| 探测包无载荷 | 纯探测 | 不计入业务数据量 |
| 收到对端确认 | 连接仍然有效 | 业务可以继续使用 |
| 连续探测无响应 | 连接已失效 | 达到探测次数后内核上报错误 |
保活间隔通常远大于 NAT 或防火墙的会话老化时间,指望它防止连接被断开往往来不及。
看到周期性小包先确认是 Keep-Alive 还是应用层心跳,两者的调优位置完全不同。
补充要点
- 先确认应用是否真的启用了保活选项,再谈参数调整
- 保活只解决「对端是否消失」的检测问题,不解决链路空闲被回收
- 内核参数是全局默认值,单个连接可按套接字选项单独设置
- 探测流量极小,对带宽与设备负载的影响通常可以忽略
把中间设备的会话老化时间与业务空闲时长放在一起比较,才能判断保活间隔是否够用。