首页/系统/Linux 内核与性能调优速查/TCP Keepalive 三参数速查
sysctl 内核参数72 条

TCP Keepalive 三参数速查

空闲连接保活探测:默认约 2 小时才发首个探测包,对穿越 NAT/防火墙的长连接通常过慢,需要按链路回收时间调小。

TCP Keepalive 是什么

TCP 保活是一组探测机制:连接空闲到一定时间后,内核向对端发送不带数据的探测报文,连续多次无响应就判定连接已死并通知应用。三个全局参数分别控制首个探测的等待时间、探测间隔和失败判定次数,默认组合约需 2 小时 11 分钟才会发现对端失联。它只在应用对该套接字开启 SO_KEEPALIVE 后才会生效,因此与 HTTP 层的 keep-alive、Nginx 的 keepalive_timeout 是完全不同的东西。

基本信息

tcp_keepalive_time连接空闲多久后发出首个探测,默认 7200 秒
tcp_keepalive_intvl相邻探测的间隔,默认 75 秒
tcp_keepalive_probes连续失败多少次判定断开,默认 9 次
启用条件应用需对套接字设置 SO_KEEPALIVE,否则参数形同虚设
单连接覆盖应用可用 TCP_KEEPIDLE、TCP_KEEPINTVL、TCP_KEEPCNT 单独设定
观测命令ss -o 查看连接计时器,含 keepalive 剩余时间

典型使用场景

  • 穿越 NAT 与防火墙的长连接:中间设备空闲回收后连接被静默丢弃,靠保活及早发现并重建
  • 数据库连接池与消息队列客户端:链路抖动后连接假活,业务请求挂住直到超时才失败
  • 微服务之间的长连接:希望故障节点的连接尽快被剔除,而不是等到业务超时
  • 负载均衡后端健康判断:保活能让客户端及时感知后端下线,缩短故障切换时间
  • 排查连接黑洞:应用报读超时而底层无任何 RST,用 ss -o 看保活计时器确认是否已检测到异常

查看与调整

查看与调整
sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes   # 读三参数
sysctl -w net.ipv4.tcp_keepalive_time=600    # 10 分钟空闲后开始探测
sysctl -w net.ipv4.tcp_keepalive_intvl=30    # 每次探测间隔 30 秒
sysctl -w net.ipv4.tcp_keepalive_probes=3    # 3 次无响应即判定断开
ss -o state established '( dport = :3306 )'  # timer:(keepalive,剩余时间) 观察保活状态
ss -o state established | head               # 查看全部已建立连接的计时器

落盘与回读

落盘与回读
# /etc/sysctl.d/99-keepalive.conf
net.ipv4.tcp_keepalive_time = 600     # 首个保活探测前的空闲时间
net.ipv4.tcp_keepalive_intvl = 30      # 探测间隔
net.ipv4.tcp_keepalive_probes = 3      # 失败判定次数

参数组合读法

参数默认值调整方向
tcp_keepalive_time7200 秒按链路空闲回收时间下调,需小于中间设备的回收阈值
tcp_keepalive_intvl75 秒故障发现要求快时降到 15~30 秒
tcp_keepalive_probes9 次内网稳定可降到 3 次,配合间隔缩短判定时间
默认合计约 2 小时 11 分远超多数 NAT 空闲回收时间,长连接业务通常需要调整
中间设备的空闲回收时间通常只有数百秒量级,不同厂商与型号取值不同,因此保活探测间隔应明显小于该值,让探测在连接被静默回收前发生。有条件的场景建议在应用层加心跳,语义比 TCP 保活更可控。
这是全局参数,改小会让机器上所有开启保活的连接(数据库连接池、服务间长连接、监控上报)都更频繁发探测包。在有数万长连接的节点上,探测流量与唤醒次数会同步上升,调整前先评估连接规模。
保活只能发现链路已断,无法判断对端进程是否健康。若需要业务级存活判断,应由应用心跳或健康检查承担;把保活当作健康检查会漏掉对端进程僵死但仍能回 ACK 的情况。
云主机与容器场景要留意层级:保活探测由客户端内核发出,若路径上存在 SNAT 网关,网关自身的空闲回收时间可能先到,连接在探测发出前就已被丢弃。此时需要同时核对网关侧的会话超时配置。

易错点

  • 以为改了全局参数就生效:应用没有开启 SO_KEEPALIVE 时不会发送任何探测,先确认套接字选项
  • 把 TCP 保活与 HTTP keep-alive 混为一谈:后者是应用层连接复用,参数在不同的配置文件里
  • 全局调小保活时间:数万长连接节点的探测流量与 CPU 唤醒同步上升,需要按规模评估
  • 保活间隔大于中间设备空闲回收时间:连接已被静默丢弃,探测发出时对端早已不在,问题依旧
  • 把它当健康检查使用:对端进程僵死仍能回复 ACK,应用层心跳与健康检查不可省略

数据来源与参考

  • man 7 tcp(SO_KEEPALIVE)
  • Linux 内核 Documentation/admin-guide/sysctl/net.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌