TCP 流分析82 条

TCP Keep-Alive 机制

空闲连接上定期发送无数据的保活探测(应用启用 SO_KEEPALIVE 后生效),用于发现对端失联;抓包表现为长时间空闲后周期出现的小 ACK/探测包。

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 还是应用层心跳,两者的调优位置完全不同。

补充要点

  • 先确认应用是否真的启用了保活选项,再谈参数调整
  • 保活只解决「对端是否消失」的检测问题,不解决链路空闲被回收
  • 内核参数是全局默认值,单个连接可按套接字选项单独设置
  • 探测流量极小,对带宽与设备负载的影响通常可以忽略
把中间设备的会话老化时间与业务空闲时长放在一起比较,才能判断保活间隔是否够用。

易错点

  • 把 Keep-Alive 当万能的连接保活手段:中间设备老化更快时连接照样被回收
  • 调整内核参数却未确认应用是否启用了套接字选项,配置改了但没有生效
  • 把保活探测包计入业务流量统计,导致有效载荷量被高估

数据来源与参考

  • RFC 1122(Keep-Alive)
  • Linux ip-sysctl 文档
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌