Linux默认TCP保活时长为7200秒,但需调小至小于中间设备空闲超时阈值(如光猫300秒),且必须启用SO_KEEPALIVE、确认容器网络放行探测包,三者缺一不可。

Linux系统默认的TCP保活时长(tcp_keepalive_time)是7200秒(2小时),但绝大多数公网或NAT环境根本等不到那么久——连接早被防火墙、云负载均衡器或家用路由器回收了。必须调小,否则“保持连接”就是一句空话。
怎么用sysctl临时改TCP保活启动时间
这是最快验证效果的方式,适合调试或应急,但重启后失效。
- 先查当前值:
sysctl net.ipv4.tcp_keepalive_time(默认输出net.ipv4.tcp_keepalive_time = 7200) - 设为5分钟(300秒):运行
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=3 - 注意:这三个参数共同决定总超时窗口——
300 + 3 × 30 = 390秒(约6分30秒),必须严格小于你所处网络中设备的空闲超时阈值(比如阿里云SLB默认是600秒,光猫常见是300秒)
为什么改了sysctl还是断连
因为内核参数只是“探测行为”的开关,前提是应用层socket真启用了SO_KEEPALIVE。很多服务(如MySQL客户端、PostgreSQL连接池、Nginx upstream)默认不启用它。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
- 用
ss -tni查某个活跃连接,如果输出里没有keepalive字段,说明没开 - 检查你的服务配置:例如MySQL JDBC要加
?tcpKeepAlive=true;pgBouncer需设tcp_keepalive=on;Go程序得显式调conn.SetKeepAlive(true) - 只改
/etc/sysctl.conf却不确认应用是否启用SO_KEEPALIVE,等于给一辆没点火的车调油门
setsockopt里怎么单独控制单个socket的保活时间
全局调参是一刀切,高并发服务更需要按连接类型差异化控制——比如WebSocket长连接要300秒探测,而HTTP短连接完全不需要。
- 必须两步走:先启用
SO_KEEPALIVE,再设TCP层参数:TCP_KEEPIDLE(Linux)、TCP_KEEPALIVE(macOS) - 代码示例(C):
int enable = 1; setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)); int idle = 300; // 5分钟后开始探测 setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)); int interval = 30; setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval)); int probes = 3; setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &probes, sizeof(probes));
- 坑点:旧内核(
2.6.32前)或Alpine(musl libc)可能不支持TCP_KEEPIDLE,调用返回ENOPROTOOPT,务必检查返回值
容器里改sysctl参数可能无效
Kubernetes Pod、Docker默认网络、Cilium/Calico等CNI插件,甚至eBPF防火墙规则,都可能拦截或延迟Keepalive探测包——此时/proc/sys/net/ipv4/tcp_keepalive_*写了也白写。
- 验证方式:在Pod里执行
ss -tni,看连接是否有ka_timer字段;再用tcpdump抓包确认空闲期后是否真发出ACK探测 - 若底层网络栈不可控,唯一可靠路径是叠加应用层心跳(如每30秒发
PING),别依赖TCP原生机制 - 临时绕过:测试时可尝试
hostNetwork: true,但生产环境严禁这么做
真正起作用的从来不是某个单一参数,而是SO_KEEPALIVE是否启用、tcp_keepalive_time是否小于中间设备超时、以及容器或eBPF环境是否放行探测包——三者缺一不可。很多人卡在第一步,连SO_KEEPALIVE都没开,后面全白调。

















