客户端和服务端都显示连接还在,第 900 秒后客户端 send 成功但服务端收不到数据,ss 里状态还是 ESTABLISHED。乍看像缓存或者权限的锅,追下去往往不是。

sysctl -w net.ipv4.tcp_keepalive_time=300
sysctl -w net.ipv4.tcp_keepalive_intvl=60
sysctl -w net.ipv4.tcp_keepalive_probes=3

追下去是这么回事:中间的 NAT 设备按 15 分钟回收空闲表项,回收时两端都不知情。TCP keepalive 默认要 7200 秒才发第一个探测,远晚于 NAT 的超时时间。

碰到「NAT 超时断连」这类问题,我习惯先把当前配置原样备份一份,改坏了立刻换回来,不用现场推。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

具体做法是,把 tcp_keepalive_time 调到 300 秒;探测间隔设 60 秒;探测次数 3 次后断开;应用层再叠一层 60 秒心跳。

验收就看一点,调整后连接保持 12 小时仍能正常收发,NAT 表项每 5 分钟被刷新一次。

作者 9823189