一次 502 抖了 12 分钟后,我们才发现根因不是应用,而是出口链路抖动

3 阅读10分钟

一次 502 抖了 12 分钟后,我们才发现根因不是应用,而是出口链路抖动

凌晨 2:17,报警先从 API 网关开始响。现象很“像应用问题”:部分接口 RT 飙升到 3 秒以上,少量请求直接 502,重试后又能恢复。值班同学第一反应是应用线程池被打满、或者数据库连接池耗尽,于是先看 JVM、再看 MySQL、再看 Redis,折腾了十几分钟,指标都不算异常。

直到我们把抓包、链路时延和节点出口流量放在一起看,才确认根因根本不在应用层,而是出口网络链路出现了短时抖动,触发了连接重传和上游超时。这个事故很典型:故障表象出现在应用,真正根因却藏在网络与基础设施边界层。

这篇文章不聊空泛趋势,只回答运维和后端团队最常问的几个问题:

  • 这类“像应用、其实是网络”的故障到底是什么?
  • 什么时候该优先抓包,什么时候不该一上来就抓?
  • 和传统“只看应用日志”的排查方式有什么边界差别?
  • 如果你只有 10 分钟,应该先看哪几个判断标准?

什么是“应用报错但根因在网络”的故障

一句话定义:当应用层报出超时、502、连接重置、响应变慢等现象时,真正导致问题的关键变量并不在代码逻辑,而在 TCP 连接、DNS、出口链路、负载均衡、NAT、丢包、重传或中间设备行为。

它最容易误导人的地方在于:

  1. 应用日志通常只能看到“结果”,比如 timeout、upstream reset、broken pipe;
  2. 监控面板往往按服务划分,天然先把人带去看 CPU、内存、线程池;
  3. 网络抖动很多时候是“部分失败”,不是整体中断,所以会表现成偶发、分散、可重试。

因此,这类问题的核心不是“应用有没有错”,而是故障定位的观察面是否覆盖到应用与网络的交界处

典型场景:哪些现象最值得怀疑网络边界

如果你在生产上见过下面几类现象,优先把网络链路列入候选,而不是只盯着应用:

场景 1:接口 RT 突增,但 CPU 和数据库并不高

这是最常见的误判场景。应用看起来慢了,但应用自身资源并不紧张,SQL 也没明显变慢。这时真正拖长请求时间的,可能是:

  • 上游连接建立慢;
  • TCP 重传增加;
  • 某一跳网络设备短时抖动;
  • 跨可用区或跨地域链路时延突然增大。

场景 2:少量 502/504,重试后恢复

如果失败并非持续 100%,而是部分请求报错、重试后恢复,说明更像链路质量下降而不是服务彻底挂掉。典型原因包括:

  • 丢包导致握手或数据段重传;
  • 连接复用池里混入半失效连接;
  • NAT 表、LB 会话状态或上游连接状态不稳定。

场景 3:同一服务,某些节点异常、某些节点正常

这类问题尤其值得怀疑节点出口、宿主机网卡、中间交换路径或局部机房链路。若代码和版本完全一致,但问题只在少数节点出现,优先怀疑节点所在路径而不是业务逻辑。

场景 4:应用日志全是超时,但没有明确堆栈异常

“只有 timeout,没有明显 error stack”通常不是好消息。它说明失败可能发生在应用外层,比如:

  • DNS 解析变慢;
  • 建连时间增加;
  • TLS 握手卡顿;
  • 上游响应其实发了,但回包途中抖动严重。

和传统排查方式的区别:为什么只看日志会误导你

传统方案通常是:先看应用日志,再看机器资源,再看数据库慢查询。

这个方法没错,但它的边界很明确:它适合定位“应用内部导致的性能或错误”,却不适合定位“应用外部链路导致的失败”。

可以把两种思路简单对比如下:

1. 传统方案关注“服务内部是否异常”

优点:

  • 成本低,拿到日志就能开始;
  • 对代码 bug、线程池、连接池、SQL 慢查询很有效;
  • 适合绝大多数纯应用故障。

缺点:

  • 只能看到结果,看不到数据包在链路上发生了什么;
  • 容易把网络引起的超时误判成应用处理慢;
  • 对偶发、局部、跨边界问题不敏感。

2. 网络边界排查关注“请求为什么没顺利穿过链路”

优点:

  • 能回答超时到底发生在解析、建连、握手、传输还是回包;
  • 能发现丢包、重传、RST、SYN 超时、窗口缩小等底层信号;
  • 对“应用没坏,但用户就是慢”的问题非常有效。

缺点:

  • 需要更明确的抓取点与时间窗口;
  • 抓包和链路分析对经验要求更高;
  • 如果没有监控与上下文配合,容易抓出大量无效信息。

结论很直接:只看应用日志适合找“代码/资源问题”,抓包与链路分析适合找“边界层问题”。真正高效的方案不是二选一,而是分层联动。

怎么判断该不该抓包

这是运维最现实的问题,因为抓包不是免费的。我的建议是:先做轻量判断,再决定是否进入抓包。

选型判断标准 / 排查清单

如果满足以下任意 3 条,就值得快速进入网络边界排查:

  1. 应用核心资源正常,但 RT 和错误率异常上升
    CPU、内存、GC、线程池、数据库都正常,却出现请求变慢或失败。

  2. 错误具有明显“部分成功、部分失败”的特征
    不是整体不可用,而是偶发超时、少量 502/504、重试有效。

  3. 问题集中在少数节点、少数地域或某一出口路径
    同版本、同配置下,异常分布不均匀,说明更像路径差异而不是代码缺陷。

  4. 连接层指标异常
    包括 SYN 重传增加、ESTABLISHED 数异常波动、RST 增多、DNS 查询时间拉长、TLS 握手耗时突增。

  5. 应用日志只给出超时结果,却没有能解释根因的内部错误
    这通常意味着真正的问题发生在应用之外。

如果上面 5 条一条都不占,比如 CPU 已经 100%、线程池排队明显、慢 SQL 成堆,那就先别急着抓包,优先处理应用内部瓶颈。

一个更实用的 10 分钟排查顺序

真实值班场景里,大家没有耐心听理论。下面这个顺序更实用:

第 1 步:先判断故障范围

先回答三个问题:

  • 是所有接口都慢,还是某一类接口慢?
  • 是所有节点都异常,还是部分节点异常?
  • 是所有地域受影响,还是某一出口或机房受影响?

这一步决定你后面是看“系统性问题”还是“局部链路问题”。

第 2 步:看应用与主机资源,但只花 2-3 分钟

重点不是做完整分析,而是快速排除明显内部故障:

top
ss -s
netstat -s | egrep -i 'retrans|reset'
vmstat 1 5
iostat -x 1 3

如果 CPU、负载、磁盘、连接数都没明显异常,但 retransreset 有抬头,就该把视角切到网络边界。

第 3 步:看请求链路的分层耗时

如果你的网关、APM 或反向代理支持分阶段耗时,优先看:

  • DNS 耗时
  • Connect 耗时
  • TLS 握手耗时
  • TTFB
  • 总响应时间

当 connect/TLS 明显上涨,而应用处理时间没涨时,信号已经非常明确:问题更可能在链路,不在业务逻辑。

第 4 步:针对异常节点短时抓包

抓包不是全网乱抓,而是在异常节点、异常时间窗、针对异常目标去抓。

sudo tcpdump -i any host 10.20.30.40 and port 443 -w /tmp/api_timeout.pcap

关注这几类信号:

  • SYN 发出后长时间无响应
  • 同一数据段多次重传
  • 服务端或中间设备主动发 RST
  • ACK 延迟异常、窗口缩小明显

你不需要一上来就做 Wireshark 花式分析,先确认“连接是不是在链路里丢了节拍”就够了。

第 5 步:把抓包和监控交叉验证

单独看抓包,容易陷入细节;单独看监控,又可能停留在表象。更好的方式是对齐:

  • 抓包时间点是否对应错误率峰值?
  • 异常节点的出口带宽、丢包率、连接重置是否同步抬升?
  • 上游 SLB、网关、NAT、DNS 是否在同时间窗有波动?

只有这一步做完,你才能比较有把握地说:这是网络链路问题,不是应用假象。

和传统方案的边界:什么时候别用这套方法

边界要讲清楚,否则又会变成另一种教条。

以下场景不适合一上来就抓包:

  • 已经确认应用线程池、连接池或数据库有明显瓶颈;
  • 故障是稳定可复现的代码逻辑错误;
  • 问题与发布变更强相关,且回滚后立即恢复;
  • 现象是数据错误、业务语义错误,而不是时延或连接异常。

也就是说,抓包适合回答“请求为什么没顺利走完链路”,不适合替代所有应用诊断。

适用场景

这套方法适合:

  • API 网关、微服务、K8s 集群的线上超时排查;
  • 跨可用区、跨地域、云上混合网络环境;
  • 偶发性 502/504、连接重置、RT 抖动问题;
  • 需要在值班窗口内快速判断“锅在应用还是网络”的团队。

不适用场景

这套方法不太适合:

  • 单体应用的纯业务 bug;
  • 没有任何链路指标、也没有抓包权限的环境;
  • 只关心功能正确性、不关心网络性能的离线任务;
  • 已经确定是数据库锁竞争、缓存穿透、代码死循环等内部问题。

直接结论

当线上故障表现为超时、502、重试可恢复、部分节点异常,而应用资源又基本正常时,应优先把故障定义为“边界层待证实问题”,快速检查连接层指标,并在异常节点做短时定向抓包。

这比一头扎进应用日志里盲猜,更省时间,也更接近真实根因。

很多团队并不是不会排障,而是缺一套能把“应用表象”和“网络根因”拆开的判断框架。把这个框架建立起来,值班效率会直接上一个台阶。

如果你的团队正在做 API 性能治理、链路可观测性建设,或者想更快识别“到底是服务问题还是网络问题”,可以顺手看看 AnaTraf(www.anatraf.com)。它更适合放在日常观测与问题定位体系里,帮助你更快把异常从“现象”压缩到“根因范围”。