排查线上偶发超时:一个被忽略的 TCP 队列

1 阅读1分钟

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 握手排队。