Linux TCP Keepalive参数优化解决长连接断开
长连接无故断开的常见原因
在IDC机房或云服务器环境中,TCP长连接被无故断开是常见问题。除网络设备NAT超时、防火墙策略外,Linux内核默认的TCP Keepalive参数过于保守也是重要因素。系统默认keepalive探测周期长达7200秒(2小时),且连续探测失败9次才判定连接失效,总耗时约2小时11分钟。当连接空闲时间超过中间设备(如负载均衡、NAT网关)的会话超时时间时,中间设备会静默丢弃连接表项,导致后续数据报文无响应,表现为连接被无故断开。
核心参数说明
Linux TCP Keepalive相关参数位于/proc/sys/net/ipv4/目录,可通过sysctl命令查看和修改:
- tcp_keepalive_time:连接空闲多少秒后开始发送探测报文,默认7200秒。
- tcp_keepalive_intvl:每次探测报文的间隔秒数,默认75秒。
- tcp_keepalive_probes:连续探测失败多少次后判定连接断开,默认9次。
优化方案(以内网/跨机房业务为例)
根据常见网络设备会话超时(通常为300~600秒)和业务心跳需求,建议将参数调整为:
- tcp_keepalive_time设为600(10分钟空闲即开始探测)
- tcp_keepalive_intvl设为30(每30秒探测一次)
- tcp_keepalive_probes设为3(连续3次失败即断开)
执行以下命令临时生效:
sysctl -w net.ipv4.tcp_keepalive_time=600
sysctl -w net.ipv4.tcp_keepalive_intvl=30
sysctl -w net.ipv4.tcp_keepalive_probes=3
若要永久生效,将上述配置写入/etc/sysctl.conf,然后执行sysctl -p加载。
应用层配合与注意事项
- Keepalive仅保证TCP连接在网络层面的存活,业务应用仍需设计应用层心跳以快速发现对端异常。
- 减小keepalive_time会增加系统对空闲连接的探测频率,对高并发连接数(如数十万以上)会带来一定CPU和网络开销,需根据业务实际权衡。
- 若业务处于NAT或负载均衡后端,需确保所有中间设备的会话超时时间大于tcp_keepalive_time,否则仍会出现断连。
验证效果
优化后可通过ss -o state established查看连接,输出中会显示timer字段,例如timer:(keepalive,2.000,0),表示该连接已启用keepalive计时器。使用抓包工具(tcpdump)可观察到空闲期间定时发出的TCP Keep-Alive报文(ACK包,带有载荷或seq=最后一个字节序号)。若连接因Keepalive探测失败而断开,系统日志中可能记录相关报错。建议上线前在测试环境验证参数调整对现有业务的影响。