1. 引言:KeepAlive的必要性
编写TCP服务或客户端时,大多数人都会显式开启KeepAlive。即便开发者忘记,那说明你不如让AI写,至少我现在用了几种模型,都晓得自动配置Keep Alive参数。
以Netty为例,一个简单的配置如下:
2. 默认参数的问题与Netty的优化
然而,仅开启KeepAlive还远远不够。Linux内核默认的KeepAlive空闲时间是7200秒,这个时间过长,以至于我们几乎必须同时引入应用层心跳才能及时感知连接状态。
好在较新版本的Netty允许直接在应用层设置KeepAlive的细节参数:
但这种方案只适用于高版本JDK和高版本Netty。
对于仍在使用JDK8 的老项目,这些选项无法生效。况且,真正从头编写 TCP 服务的情况并不多,大家更多依赖数据库连接池、Redis 客户端等现成的 SDK,要在这些组件中调整 KeepAlive 参数,实现方式往往比较曲折,不够通用,也不推荐。
3. 云环境踩坑实录:连接跟踪导致的RST
我对KeepAlive参数如此敏感,原因很直接:被坑过,而且每次几乎都与“上云”有关。
早期在移动云上部署IoT项目进行压测时,我们在内网部署模拟客户端。压力测试过程中发现,模拟终端与IoT服务端之间的连接总是莫名其妙被RST,连接数也打不上去,即便主机和网络规格都很高。
排查后定位到,终端默认的心跳间隔为10分钟,超过了移动云安全组连接跟踪的默认超时时间,导致安全组直接发送RST断开连接。更严重的是,安全组的连接跟踪本身有性能开销,当多台主机之间接近20万连接时,网络能力直接被打满。
最近读到《AWS连接超时根因分析》(https://plantegg.github.io/2026/04/15/AWS-HikariCP-连接超时根因分析/)一文,才发现这几乎是一个通病。那个案例更加离谱——连接异常时不发送 RST,而是默认吞掉异常信息,让排查难上加难。
4. 后续的排查思路
自那次踩坑之后,凡遇到类似的莫名不通或RST现象,我都会第一时间请相关同事确认链路上是否存在网关、安全组或负载均衡设备;一旦存在,就提醒调整相应的超时时间。
但必须承认,负载均衡的超时设置多数只对HTTP流量友好,针对IoT等长连接设备,通常需要提交工单才能完成调整。
5. 最简单可靠的方式:直接配置Linux内核参数
最直接、最普适的方案,是在云主机上手动配置 TCP 内核参数:
cat >> /etc/sysctl.conf << 'EOF'
net.ipv4.tcp_keepalive_time = 120
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
EOF
完成配置后,可以规避大量由云网络中间件引起的连接中断问题。有人可能担心这会增加一些网络负载,但在机房或云环境内部,这类开销几乎可以忽略不计。更重要的是,这套配置能帮助我们快速发现应用异常——例如 MySQL 节点异常下线时,不必等到业务高峰期才发现连接早已处于实际断开的状态。