linux默认tcp keepalive参数过于保守,需调优tcp_keepalive_time(建议600秒)、tcp_keepalive_intvl(建议30秒)、tcp_keepalive_probes(建议3次)以适配nat/负载均衡器5–60分钟超时,总断连超时约11分30秒,并须配合应用层心跳确保可靠性。

Linux默认的TCP Keepalive参数太保守,空闲2小时才发第一个探测包,而很多NAT设备、云负载均衡器(如AWS ALB、阿里云SLB)会在5–60分钟内主动清理空闲连接。这就导致连接“悄无声息”断开,应用层却还误以为连着。调优tcp_keepalive_time、tcp_keepalive_intvl和tcp_keepalive_probes三个参数,能让系统更早发现并处理断连,是解决长连接被中间设备误杀的关键一步。
理解三个核心参数的实际作用
Keepalive不是心跳开关,而是内核对空闲连接的被动探测机制:
- tcp_keepalive_time:连接空闲多少秒后,开始发第一个探测包。默认7200秒(2小时),通常需大幅缩短
- tcp_keepalive_intvl:第一次探测无响应后,每隔多少秒再发一次。默认75秒,建议设为20–60秒之间
- tcp_keepalive_probes:连续多少次探测失败后,内核才关闭该连接。默认9次,生产环境常设为3–5次,避免等待过久
举例:设为time=600、intvl=30、probes=3,意味着空闲10分钟后开始探测,每30秒一次,3次无响应即断连——总超时约11分30秒,远快于默认的2小时11分。
用Sysctl临时调整验证效果
适合快速测试或调试,重启后失效,但能立刻生效:
- 查看当前值:
cat /proc/sys/net/ipv4/tcp_keepalive_timecat /proc/sys/net/ipv4/tcp_keepalive_intvlcat /proc/sys/net/ipv4/tcp_keepalive_probes - 设为推荐值(需root权限):
sudo sysctl -w net.ipv4.tcp_keepalive_time=600sudo sysctl -w net.ipv4.tcp_keepalive_intvl=30sudo sysctl -w net.ipv4.tcp_keepalive_probes=3
执行后,所有新启用SO_KEEPALIVE的套接字(包括sshd、nginx upstream、数据库客户端等)都会立即按新规则工作。
写入/etc/sysctl.conf实现永久生效
生产环境必须做这步,否则重启就恢复默认:
- 编辑配置文件:
sudo nano /etc/sysctl.conf - 在末尾添加三行(若已存在同名项,直接覆盖):
net.ipv4.tcp_keepalive_time = 600net.ipv4.tcp_keepalive_intvl = 30net.ipv4.tcp_keepalive_probes = 3 - 加载新配置:
sudo sysctl -p
注意:该配置影响全局所有TCP连接,不区分服务类型。如果某些服务有特殊需求(如SSH需更激进保活),建议配合sshd_config单独设置TCPKeepAlive和ClientAlive参数。
配合应用层心跳才能真正可靠
TCP Keepalive只能确认链路是否通,无法判断远端进程是否卡死、是否还在处理请求。它也穿不透四层代理的连接老化表。因此:
- 数据库连接池应开启自身健康检查(如HikariCP的
connection-test-query) - 微服务间建议用gRPC keepalive或HTTP/2 PING帧
- Redis客户端应定期发送
PING命令并校验响应 - Keepalive只是兜底手段,不能替代业务层设计
单纯调小内核参数,不加应用层配合,仍可能在NAT超时后出现“连接看似存在,实则不可用”的问题。











