首页/系统/Linux 内核与性能调优速查/应用侧 TCP keepalive 参数
网络栈调优98 条

应用侧 TCP keepalive 参数

在单个连接上开启保活并定制空闲、间隔与次数, 用于快速回收异常对端连接。

什么是应用侧 TCP keepalive

TCP keepalive 让内核在连接空闲一段时间后主动发送探测报文,连续若干次没有回应就判定对端不可达并关闭连接,从而回收“对端已经消失但本端还认为是 established”的连接。它按 socket 生效:应用可以在单个连接上开启并定制空闲时间、探测间隔与失败次数,比改系统级 tcp_keepalive_* 参数更精确(系统参数只影响未单独设置的连接)。

基本信息

开启setsockopt(SOL_SOCKET, SO_KEEPALIVE, &one, ...)
空闲时间TCP_KEEPIDLE(秒)
探测间隔TCP_KEEPINTVL(秒)
失败次数TCP_KEEPCNT
系统级对应net.ipv4.tcp_keepalive_time / _intvl / _probes
生效范围仅对该 socket,且需连接处于空闲状态

典型使用场景

  • 长连接服务回收僵尸连接:客户端异常断电或网络中断后及时释放资源
  • 负载均衡后端:确认空闲连接不会长期占用会话表项
  • 中间设备的超时策略差异:把探测时间设为小于设备空闲回收时间
  • 与中间设备 NAT 表老化时间配合,避免连接被静默清除后应用仍在使用
  • 连接池健康检查的补充手段

C 用例

C 用例
int one = 1, idle = 60, intvl = 10, cnt = 3;
/* 开启保活 */
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
/* 空闲 60 秒后开始探测 */
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle));
/* 每 10 秒探测一次,连续 3 次无响应则断开 */
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt));

查看系统默认与连接状态

查看系统默认与连接状态
sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes
ss -to state established | head -5    # timer 字段可看出 keepalive 计时
ss -tno | grep -m3 'timer:(keepalive'

参数与行为

参数含义调整注意
SO_KEEPALIVE是否开启保活默认关闭,需显式开启
TCP_KEEPIDLE空闲多久开始探测应小于中间设备的空闲回收时间
TCP_KEEPINTVL探测间隔过密会增加无效流量
TCP_KEEPCNT失败几次判定断开结合业务超时容忍度设置
保活探测只对空闲连接起作用:有数据往来的连接不依赖它来检活,所以不能把它当成覆盖所有情况的健康检查手段。
系统级 tcp_keepalive_* 只影响未单独设置的连接,且修改后对新连接生效;用它替代应用层心跳,往往达不到业务要求的探活时效。

易错点

  • 用保活代替应用层心跳,无法满足业务要求的超时探测精度,故障感知仍然滞后
  • 只改系统参数,已有连接不受影响,验证时必须用新建立的连接
  • 保活时间与中间设备(NAT、防火墙)的空闲回收时间不匹配,出现连接被静默清除但应用仍在使用的情况
  • 探测间隔设置过密造成额外流量与日志噪音,在大量长连接场景下反而增加负担

数据来源与参考

  • man 7 tcp
  • man 7 socket
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌