直接回答:完全两回事。HTTP Keep-Alive 是应用层特性:一个 TCP 连接上复用多个请求/响应,省握手开销,现代默认开启。TCP keepalive 是传输层保活探测:连接空闲超过阈值(Linux 默认 2 小时!)后发空包探活,检测对端是否消失。半开连接问题——对端断电/断网没发 FIN,本端认为连接还活着——TCP keepalive 理论上能发现,但两小时默认在移动/NAT 时代形同虚设,所以应用层心跳才是事实标准

展开解析:生产里的失效链条:NAT 映射几分钟到几十分钟过期、LB 空闲超时(常见 60~300 秒)静默丢连接、防火墙老化会话——这些设备不通知任何一方,下次发包才失败。设计原则:应用心跳间隔必须小于路径上最短的空闲超时(WebSocket ping 常 30 秒);发心跳还有保活 NAT 的副作用。客户端侧配合:发送失败要区分"连接已死"重试与幂等性风险(请求可能已到服务端);读超时和写超时分别设置。配置细节:Linux 的 tcp_keepalive_time/intvl/probes 可系统级调整,Go 的 Dialer 默认 15 秒应用级 keepalive。连接池要验证借出连接活性(ping 或 test-on-borrow),否则拿到死连接报错是高频线上事故。

追问方向:为什么 TCP keepalive 默认这么保守?HTTP/2 的 PING 帧角色?NAT 超时与运营商差异?

(约 460 字)