根本原因是TCP Keepalive未启用或参数保守:默认tcp_keepalive_time=7200秒远超NAT/防火墙5–10分钟空闲超时,需设为300–600、intvl=20–60、probes=3–5,并确保应用层显式启用SO_KEEPALIVE。

理解三个核心参数的实际作用
Keepalive 不是“心跳开关”,而是内核对已启用该功能的连接进行的被动探测机制:
- tcp_keepalive_time:连接空闲多少秒后发送第一个探测包。默认 7200(2 小时),建议设为 300~600(5~10 分钟),必须小于你所处网络中最短的空闲超时阈值
- tcp_keepalive_intvl:两次探测之间的间隔(秒)。默认 75,建议 20~60,太小易被误判为扫描流量,太大则响应延迟
- tcp_keepalive_probes:连续无响应后判定连接失效的探测次数。默认 9,建议 3~5;设为 1 容易因单次丢包误断,设为 0 则禁用探测
例如 time=600、intvl=30、probes=3,总探测窗口为 600 + 3×30 = 690 秒(约 11.5 分钟),比默认的 2 小时 11 分钟更贴近真实网络环境。
临时修改:快速验证与调试
适用于测试、排障或短期调整,重启后失效:
- 查看当前值:sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes
- 立即生效(需 root):
sudo sysctl -w net.ipv4.tcp_keepalive_time=300
sudo sysctl -w net.ipv4.tcp_keepalive_intvl=30
sudo sysctl -w net.ipv4.tcp_keepalive_probes=5 - 验证写入效果:cat /proc/sys/net/ipv4/tcp_keepalive_*
永久生效:生产环境必备
避免重启后恢复默认值,推荐使用 /etc/sysctl.d/ 独立配置文件(比直接改 /etc/sysctl.conf 更清晰、不易冲突):
- 创建配置文件:sudo nano /etc/sysctl.d/99-tcp-keepalive.conf
- 写入三行(注意等号前后有空格):
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5 - 加载全部配置:sudo sysctl --system(比 sysctl -p 更健壮)
应用层必须显式启用 SO_KEEPALIVE
内核参数只是定义“如何探测”,但每个 socket 默认不开启 Keepalive。光调 sysctl 而不启用选项,探测根本不会发生:
- 验证是否启用:用 ss -ti 查看某连接,输出含 keepalive 字样才表示已生效
- C 示例:
int opt = 1;
setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &opt, sizeof(opt)); - Python 示例:
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) - 若需精细控制单个连接(如 WebSocket 保活而 API 请求不保活),应在 connect 前设置 TCP_KEEPIDLE、TCP_KEEPINTVL、TCP_KEEPCNT(Linux 3.7+ 支持,优先级高于 sysctl)


















