今天生产测试机执行批量测试时发生卡死,1252 条用例全部处于等待状态,执行数为 0。进程持续运行但 CPU 占用为 0,日志停在资源清理阶段的 8 个并发 HTTP 请求,此后不再产生响应。
根因是网络路径 MTU 黑洞与程序缺少超时保护共同作用。 测试机访问土耳其区域的两个边缘 IP 时,TCP 三次握手正常,但 TLS 握手始终无法完成。抓包与 DF Ping 测试表明,该路径 MTU 约为 1483 字节,而双方仍按 1500 字节通信;中间设备静默丢弃超限报文,且未返回 ICMP 分片所需错误信息。由于服务端 TLS 响应报文丢失,连接持续重传,客户端始终收不到完整数据。
程序层面,HTTP 请求未配置 timeout_ms 时显式传入 timeout=None,关闭了 httpx 默认超时机制;同时,PLAN SETUP 钩子缺少看门狗,导致资源清理请求无限等待,整个批次无法进入用例阶段。排查未发现本地代码或网络配置变更,问题大概率来自外部链路,具体责任节点尚待云厂商确认。
修复采取网络止血与代码防御两条路径。 网络侧针对两个故障 IP 将 TCP MSS 限制为 1400,并通过 systemd 实现持久化及定时更新。修改后,两条链路的 TLS 握手分别在 0.577 秒和 0.394 秒内完成,HTTP 返回 401,证明连接已恢复。代码侧补充默认 60 秒请求超时、钩子超时看门狗、区域连通性预检,以及 PLAN HOOK 非阻塞失败机制;129 项单元测试全部通过。
截至记录时,MSS 修复已生效,代码已提交,但尚未部署到生产目录,旧批次仍未终止,新批次也尚未重跑。后续需完成部署与回归验收,并向运维部门和阿里云反馈路径 MTU 问题。
经验总结: 网络故障不可避免,但请求必须有超时、任务必须有隔离与降级机制,前置检查应尽早暴露区域故障,避免单个依赖异常拖垮整批任务。
技术原理:PMTU 黑洞与 TCP MSS 钳制
PMTU(Path Maximum Transmission Unit,路径最大传输单元) 是网络路径上能够传输的最大 IP 报文长度。以太网常见 MTU 为 1500 字节,但跨境网络、隧道或中间设备可能将实际路径 MTU 降低至 1483 字节。如果发送端仍按 1500 字节发送报文,而中间设备静默丢弃超限报文,又未返回 ICMP“需要分片”消息,双方就无法正确调整报文大小,形成 PMTU 黑洞。
TCP 的 MSS(Maximum Segment Size,最大报文段长度)用于限制单个 TCP 段的数据载荷,不包含 IP 和 TCP 头部。IPv4 无选项时,两者通常合计占用 40 字节。因此,MSS 设为 1400 时,单个 IP 报文通常不超过 1440 字节,低于本次实测的 1483 字节路径 MTU,可以避开超限丢包。
Linux 使用 iptables 的 TCPMSS --set-mss 1400 修改本机发出的 SYN 报文中的 MSS 通告值,使对端在后续发送数据时采用更小的 TCP 段。该规则只影响新建连接,不会修复已经建立的卡死连接。需要注意,MSS 是 TCP 载荷上限,并非绝对报文长度保证;TCP 选项、封装开销等因素仍需考虑。
本次实测中,修复前 TCP 连接成功但 TLS 握手超时;钳制 MSS 后,两个故障 IP 均返回 HTTP 401,且 TLS 握手恢复,证明网络连接已恢复。401 表示请求到达应用层但缺少有效鉴权,并不代表业务请求成功。