已采纳
回答正文
回复
讨论正文
该问题的正文、回答与讨论。
背景
15 年网络工程,现在保一批跨机房长连接池(gRPC over HTTP/2 + 一批 HTTP/1.1),单侧连接数 2 万上下。最头疼的一类故障不是"链路断了",而是对端节点静默死亡(断电、内核 panic、网络分区、交换机黑洞)——socket 进入 half-open:本端完全不知道对端已经不在了,直到某次应用层 read/write 真正打到它,请求就一路 hang 到某个上层超时(我们 30–60s)才失败,期间连接池里这条连接一直被复用,把坏连接"养"在池里。
我想在探测开销可控的前提下,尽快把死对端识别并剔除,而不是靠应用层心跳硬扛。
现象
已尝试的排查与结果
net.ipv4.tcp_keepalive_time=7200s:太慢,基本等于没开;tcp_keepalive_time=60s / intvl=10s / probes=3:能识别,但我担心两点——(a) 高负载/拥塞链路上正常的重传延迟会不会被误判成"死",把慢对端当死对端砍掉;(b) 2 万连接 × keepalive 探测的额外包量到底多大,我在 25G 链路上没实测过这笔账;期望得到的答案形态
tcp_keepalive_time / intvl / probes),并说明这套参数下"死对端"和"慢对端"在抓包上怎么区分(RST/FIN/无 ACK vs 有重传),避免误判;SO_LINGER、HTTP/2 GOAWAY / PING、连接池 idle 探测),以及它们各自的代价。参考:#896 里那位同学遇到的"抓包 RTT 正常但应用层超时",我猜部分根因就是 half-open 没被及时识别;#90 讨论过"网络观测做到什么程度算够",我觉得 keepalive 参数预算正是"够用"这条线上最常被默认忽略的一块。