本文目录导读:

在 Linux 系统中,tcp_keepalive_intvl 的间隔行为取决于你是在修改系统全局参数(通过 sysctl),还是在设置单个 socket 的选项(通过 setsockopt)。
以下是详细的解释和配置方法:
核心概念:它控制什么?
tcp_keepalive_intvl 定义的是发送探测包的间隔时间,它指的是:在连接处于 keepalive 探测阶段时,连续两次发送探测包之间的时间间隔。
- 单位:秒(整数)。
- 默认值:通常是 75 秒(在某些发行版或内核版本中可能是 15 秒)。
工作流程(了解“间隔”发生的时机)
假设一个 TCP 连接已经开启了 keepalive,且空闲了足够长的时间,它的探测流程如下:
- 开始空闲:连接建立后,开始空闲计时。
- 触发首次探测:当空闲时间达到
tcp_keepalive_time(默认 7200 秒,即 2 小时)时,内核发送第一个 keepalive 探测包。 - 等待响应:内核等待对端的 ACK 响应,如果对端正常,会回复 ACK,连接保持,空闲计时器重置。
- 如果无响应:如果对端没有回复 ACK,内核不会立即断开连接,而是等待
tcp_keepalive_intvl秒。 - 发送第二次探测:在等待了
tcp_keepalive_intvl秒后,如果依然没有收到响应,内核发送第二个 keepalive 探测包。 - 重复步骤 4-5:持续发送探测包,每次间隔
tcp_keepalive_intvl秒。 - 放弃连接:在发送了
tcp_keepalive_probes(默认 9 次)次探测且均无响应后,内核最终断开连接。
简单总结:tcp_keepalive_intvl 是连续两次探测发送之间的“等待-重试”间隔。
如何配置(修改间隔)
方法 A:修改系统全局参数(影响所有新连接)
使用 sysctl 命令,或者直接编辑 /etc/sysctl.conf 文件。
-
临时修改(重启后失效):
# 将间隔改为 10 秒 sudo sysctl -w net.ipv4.tcp_keepalive_intvl=10
-
永久修改: 编辑
/etc/sysctl.conf(或/etc/sysctl.d/下的文件),添加或修改以下行:# 设置 keepalive 探测间隔为 20 秒 net.ipv4.tcp_keepalive_intvl = 20
然后执行
sudo sysctl -p使其生效。
方法 B:修改单个应用程序的 socket(不影响其他程序)
在 C/C++ 或 Python 代码中,使用 setsockopt 函数设置 TCP_KEEPINTVL 选项,这允许你为特定连接设置与系统默认值不同的间隔。
-
C 语言示例:
#include <sys/socket.h> #include <netinet/tcp.h> // 包含 TCP_KEEPINTVL int keepalive_intvl = 10; // 间隔 10 秒 setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &keepalive_intvl, sizeof(keepalive_intvl));
-
Python 示例:
import socket # ... 创建 socket s ... s.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10) # 间隔 10 秒
-
注意:使用代码设置时,你通常还需要设置
TCP_KEEPIDLE(空闲时间)和TCP_KEEPCNT(重试次数)。
完整的 keepalive 参数速查表
| 参数 | sysctl 变量名 | setsockopt 常量名 | 默认值 | 说明 |
|---|---|---|---|---|
| 空闲时间 | net.ipv4.tcp_keepalive_time |
TCP_KEEPIDLE |
7200 秒 | 连接空闲多久后开始发送第一个探测包 |
| 探测间隔 | net.ipv4.tcp_keepalive_intvl |
TCP_KEEPINTVL |
75 秒 | 探测无响应时,重试的间隔时间 |
| 重试次数 | net.ipv4.tcp_keepalive_probes |
TCP_KEEPCNT |
9 次 | 连续无响应多少次后断开连接 |
常见问题和最佳实践
-
间隔太短(1 秒):
- 风险:如果对端网络不稳定,可能会误判对方掉线,导致连接被断开,同时会产生大量的探测包,增加网络开销和 CPU 使用率。
- 适用场景:适合对连接高可用要求极高、能容忍少量误杀的场景(如金融交易、实时游戏)。
-
间隔太长(300 秒):
- 风险:当对端崩溃或网络断开时,你的应用程序可能需要等待很长时间(
时间 + 间隔 * 次数)才能发现连接已中断。 - 适用场景:适合对连接中断不太敏感、更关注节省网络资源的场景(如长连接服务器间的状态同步)。
- 风险:当对端崩溃或网络断开时,你的应用程序可能需要等待很长时间(
-
如何计算总超时时间? 如果一个连接对端无响应,从开始空闲到最终断开连接的总等待时间为:
tcp_keepalive_time + (tcp_keepalive_probes - 1) * tcp_keepalive_intvl(第一次探测包发送后,后面probes - 1次都是按intvl间隔发送的)。默认参数:
7200 + (9 - 1) * 75 = 7200 + 600 = 7800 秒(约 2 小时 10 分钟)。
tcp_keepalive_intvl 控制的是多次探测包发送之间的间隔时间,单位是秒,修改它通常是为了加快或减慢检测对端是否离线的速度,建议在修改前明确你的业务对“及时性”和“网络负载”的容忍度。