排查线上偶发超时:一个被忽略的 TCP 队列
1、问题
核心接口偶发超时,服务端平均响应 100ms,客户端却报 2s+ 超时。重启无效,网络监控正常。
2、排查
服务端日志显示:请求到达时间比客户端发送时间晚了将近 2s。问题不在服务内部,在请求到达之前。
抓包发现:客户端发 SYN,服务端 1.8s 后才回 ACK。TCP 握手被阻塞。
查系统日志: Possible SYN flooding on port 8080. Sending cookies.
根因是 tcp_max_syn_backlog 只有 128。K8s 节点上几十个 Pod 共用端口,高峰期新建连接数打满 SYN 队列,内核延迟处理新连接。
3、为什么只影响一个接口
其他接口走 HTTP Keep-Alive,长连接已建立。唯独这个接口的客户端每次请求都新建连接,正好踩中瓶颈。
4、解决
调大 SYN 队列: tcp_max_syn_backlog 和 somaxconn 都改成 4096
客户端改长连接:避免每次新建 TCP 连接,新建连接数下降 90%
纳入基线:K8s 节点的网络内核参数统一配置,别等出事再改
5、经验
服务端快、客户端慢,优先怀疑网络层和传输层
偶发问题必须抓包,日志只能告诉你发生了什么,抓包能告诉你为什么
K8s 多 Pod 共享内核参数,一个服务的连接风暴能拖累同节点其他服务
老旧客户端(不保持连接)是隐藏炸弹,服务端再稳也扛不住
一句话总结:超时不一定慢在代码,可能卡在 TCP 握手排队。
浙公网安备 33010602011771号