一次线上接口随机超时排查:从抓包到定位 MTU 黑洞的完整实战

3 阅读9分钟

一次线上接口随机超时排查:从抓包到定位 MTU 黑洞的完整实战

周一早上 9 点 20,业务群开始有人@运维:新版本刚发完,部分用户访问上传接口一直转圈,Web 页面偶发超时,但奇怪的是首页、登录、查询接口都基本正常。更诡异的是,同一个接口在公司 Wi-Fi 下复现概率很低,换到某些地区运营商网络后,失败率明显升高。

第一反应往往是应用发布有问题、数据库慢查询、或者网关限流。但这次排查里,应用日志平静得像什么都没发生过,Nginx access log 里只留下少量 499 和 504,服务端 CPU、内存、连接数都在正常区间。表面看是“应用超时”,但真正的锅,其实埋在网络路径里。

这篇文章我按真实排障思路复盘一次:如何通过分层验证、抓包比对和协议细节,定位一个典型的 MTU 黑洞问题。如果你也遇到过“ping 正常、TCP 能建连、就是部分请求莫名卡死”,这套方法大概率能帮你少走很多弯路。

一、故障现象先定边界:不是全站挂,而是“大包请求”容易死

先把现象整理成几个确定事实:

  • 首页和轻量接口大多正常
  • 文件上传、带较多 Header 的 POST 请求更容易超时
  • TCP 三次握手可以成功
  • 服务端应用没有明显异常栈
  • 特定网络路径下更容易复现

这类现象非常关键。因为它说明:

  1. 不是基础连通性全断,否则握手都起不来;
  2. 不是服务端完全不可用,否则所有请求都会挂;
  3. 问题与报文大小或链路路径强相关

很多人一看到超时就扎进 JVM、线程池、数据库连接池里猛翻,最后翻了半天,发现自己在给空气做根因分析。

二、排障顺序:先证伪应用,再下钻到传输层

我通常按下面的顺序走,尽量每一步都能缩小范围:

1)应用层自检

先确认服务本身是不是健康:

curl -s -o /dev/null -w '%{http_code} %{time_total}\n' https://api.example.com/health
curl -v https://api.example.com/upload -H 'Content-Type: application/json' -d '{"x":"test"}'

同时看服务端指标:

  • 应用 RT 是否整体升高
  • 上游网关是否有 5xx 激增
  • 主机 CPU、load、内存、socket backlog 是否异常
  • Nginx/Envoy 是否存在 upstream connect timeout / read timeout

结果是:健康检查正常,小请求正常,大一点的请求偶发卡死。说明应用大概率不是第一现场。

2)传输路径验证

接着做最小化测试,验证是否与包大小有关:

ping api.example.com
tracepath api.example.com
curl --http1.1 -v https://api.example.com/some/api

如果你的环境里 tracepath 可用,它对发现路径 MTU 很有帮助。那次现场里,ping 正常,但 tracepath 显示路径 MTU 有明显下降,已经开始有味道了。

三、开始抓包:不要一上来抓全量,先抓关键点

抓包最怕两件事:一是抓太多,自己淹死在数据里;二是只在一个点抓,最后凭想象补链路。

这次我在三个位置抓:

  • 客户端出口
  • 反向代理/Nginx 所在主机
  • 应用服务器网卡

最基础的命令如下:

tcpdump -i any -nn host api.example.com and tcp port 443 -w /tmp/client-side.pcap

如果已经知道某个客户端源 IP:

tcpdump -i eth0 -nn 'host 10.10.20.35 and tcp port 443' -w /tmp/nginx.pcap

抓包时有两个原则:

  • 只抓与问题请求相关的五元组,别把全机房流量都拖进来
  • 复现时记录精确时间点,方便和应用日志、网关日志对齐

四、从 Wireshark 里看到了什么:握手成功,数据发送后卡在重传

把包导进 Wireshark 后,先按流过滤:

tcp.stream eq 7

很快能看到一个典型模式:

  1. Client 发起 SYN
  2. Server 返回 SYN, ACK
  3. Client ACK,连接建立
  4. Client 发起 TLS Client Hello
  5. 后续大一点的数据段发送后,开始出现重复重传
  6. 对端迟迟不返回 ACK,最终应用层超时

这说明不是“连不上”,而是连接建立后,某些报文在链路中被悄悄吃掉了

Wireshark 里还出现了几个很有价值的线索:

  • TCP Retransmission
  • Dup ACK 很少,甚至没有
  • ICMP fragmentation needed 没有出现

看到这里,经验值高一点的人脑子里基本会冒出四个字:MTU 黑洞

五、什么是 MTU 黑洞:不是包大,而是“该分片/该通知时没人通知”

简单说,链路上的某一段实际 MTU 比两端认为的更小。如果发送方开启了 PMTUD(路径 MTU 发现),理论上中间设备应该在报文过大时返回 ICMP “Fragmentation Needed”,告诉发送方把包发小一点。

问题在于,很多现实网络环境并不理想:

  • 某些隧道、专线、VPN、云联网叠加后,实际 MTU 变小
  • 中间防火墙把相关 ICMP 丢掉了
  • 安全策略过于“硬核”,把本来有用的控制报文一并干掉

结果就是:发送方继续发大包,中间设备继续静默丢弃,双方谁都没明说,连接就像进入冷战。用户看到的现象就是:不是报错,而是一直等

六、怎么验证是不是 MTU 问题:三种高效办法

方法 1:禁止分片探测

Linux 下可以快速测:

ping -M do -s 1472 api.example.com

这里 1472 是因为以太网常见 MTU 1500,减去 IP 和 ICMP 头部后大约是这个量级。然后逐步往下调:

ping -M do -s 1464 api.example.com
ping -M do -s 1400 api.example.com
ping -M do -s 1360 api.example.com

如果大包不通、小包通,就非常接近真相了。

方法 2:看 MSS 协商值

TCP 握手里可以看 MSS:

tcp.options.mss_val

如果链路上存在 PPPoE、GRE、IPsec、VXLAN 等封装,但边界设备没有正确做 MSS Clamp,就很容易出现“握手没问题,传数据就出事”。

方法 3:比对正常链路和异常链路

这一步特别重要。单看异常包,很容易脑补;拿一份正常流量对照,定位速度会快很多。

那次我们把公司内网正常链路和某地区用户异常链路做对比,发现前者 TLS 大包交互顺畅,后者在超过某个阈值后明显开始重传。差异一下就站出来了。

七、最终根因:云专线叠加 IPsec 后 MTU 降低,但防火墙又屏蔽了 ICMP

最后沿链路查配置,发现问题出在一段跨区域网络:

  • 业务流量从运营商网络进入边界
  • 再通过云专线转发到目标 VPC
  • 中间又叠了一层 IPsec 隧道

理论 MTU 已经不是 1500 了,但边界设备没有对 TCP MSS 做相应调整;更糟糕的是,防火墙策略把必要的 ICMP fragmentation needed 也拦掉了。

于是形成了完美风暴:

  • 小请求能过,所以监控里不是全红
  • 三次握手能成,所以很多人误以为网络没问题
  • 大包在中间静默丢弃,所以应用侧只看到超时

这类故障特别“阴”,因为它不像链路 down 那样直白,而是专挑业务高峰、复杂请求和特定路径下手。

八、修复方案:别只修当前故障,要补上机制

现场修复我们做了三件事:

1)在边界设备开启 MSS Clamp

核心目标是让两端在握手阶段就协商出更保守的报文大小。

不同设备配置方式不一样,思路类似:

# 示例思路,非特定厂商命令
set tcp-mss 1360

如果你在 Linux 网关上,也可能会用到:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360

或者更稳一点:

iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

2)放行必要的 ICMP 类型

不是所有 ICMP 都该一刀切。很多团队把“禁 ICMP”当成安全动作,结果最后安全没提升,排障地狱倒是自己亲手搭好了。

至少要审视以下控制报文是否被误拦:

  • fragmentation needed
  • time exceeded
  • destination unreachable

3)补一条面向网络质量的监控

传统监控喜欢看:CPU、内存、带宽、丢包率。但这类问题需要更细的指标,比如:

  • TCP 重传率
  • RTT 抖动
  • SYN 成功率与首包时延
  • 特定地域/运营商维度的请求成功率
  • 大对象传输成功率

如果没有这些维度,很多网络故障在监控盘上会伪装成“应用偶发慢”。

九、这类问题为什么值得写进团队排障手册

因为它高度典型,而且会反复出现。尤其在这些场景里:

  • 多云互联
  • VPN / 专线 / SD-WAN
  • 容器网络叠加封装
  • 海外访问回源
  • 大量 HTTPS / gRPC / 上传下载业务

建议把下面这份 checklist 固化:

1. 先确认是全量失败还是大包/特定路径失败
2. 检查握手是否成功、是否存在大量重传
3. 对比正常链路与异常链路抓包
4. 验证 path MTU、MSS、ICMP 是否正常
5. 审视隧道/专线/云联网叠加后的真实 MTU
6. 修复后补充长期监控与基线

这能显著减少“大家都以为是应用问题,结果折腾半天发现是网络”的经典内耗。

十、结语

网络排障最怕的不是难,而是“像”。像应用慢、像数据库抖、像网关抽风、像发布事故,但偏偏不是真凶。真正高效的排障,不靠灵感,而靠分层验证、证据闭环和抓包对照。

如果你的环境里经常遇到接口超时、跨地域访问卡顿、上传下载偶发失败,建议把路径 MTU、TCP 重传、地域链路差异纳入常规观测范围。很多所谓“玄学故障”,本质上只是缺一双能看见流量细节的眼睛。

像 AnaTraf 这类网络流量分析与可观测产品,适合用来补齐这部分能力:不仅能看带宽,更重要是把连接质量、异常会话、重传趋势和链路行为呈现出来,避免每次都等业务报警后再临时开抓包。真到线上出事时,少一点猜测,就少一点无效加班。更多信息可见:www.anatraf.com