结论先行:调用外部接口变慢时,双方的结论常常相反,因为各自看的都是自己那一侧的日志。要让它变成一次可比较的对账,得做三件事:在同一时间轴上比三段耗时(我方发出后多久收到首字节、对方处理用了多久、返回途中有多长)、双方各留一份可对齐的记录、以及事先约定出问题时谁在多久内提供什么。三件事里任何一件缺,对账就退化成各说各话。
本文只谈外部调用变慢之后怎么定位责任、拿什么材料主张,不谈内部系统变慢该按什么顺序排查,也不谈链路上的调用数和业务笔数为什么对不上。
为什么会变成各说各话
四个原因,都很普通。
其一,测量的位置不同。我方记录的是「从发出请求到收到响应」的总耗时,对方记录的是「从收到请求到发出响应」的处理耗时。两个数字之间夹着两段路:请求在网络上走的时间,和响应回来的时间。这两段不计入任何一方的记录,但它们可能占掉大半。
其二,时钟不同步。两边的服务器时间可能差几十秒甚至几分钟。把两份日志并排看,一件事在两边显示在不同的时刻,于是「谁先谁后」永远说不清。
其三,起点定义不同。我方可能从「业务发起」开始算,包含排队与序列化;对方从「收到完整报文」开始算。同样是三秒,一边觉得是自己慢,一边觉得是对方慢。
其四,样本不对齐。双方各取了一百条记录做统计,取的却不是同一批请求。平均值比出来了,比的是两个不同的样本。
四个原因里,前两个是技术问题,有办法解决;后两个是口径问题,只能靠事先约定。
同一时间轴上的三段
要让它可比,需要把一次调用拆成三段。
| 段 | 从哪到哪 | 谁能测到 | 变长说明什么 |
|---|---|---|---|
| 去程 | 我方发出到对方收到 | 两边记录相减可得 | 链路、跨境、代理或限流 |
| 对方处理 | 对方收到到对方发出响应 | 只有对方能测 | 对方系统或下游依赖 |
| 回程 | 对方发出到我方收到 | 两边记录相减可得 | 链路拥塞或响应体积过大 |
三段拆开之后,责任归属就清楚了:去程与回程的问题在链路,对方处理段的问题在对方。真正的难点是——我方拿不到对方处理段的数字,除非对方愿意提供。
可行的替代手段有三个。
用统一的请求标识串联。每次调用生成一个统一的标识,放在请求头里发出去。对方如果愿意在响应里带回这个标识并记录,两边就能按标识对齐。这是最省事的办法,成本是双方各做一点改造。
用对方提供的调用记录。不少外部服务提供调用明细查询或对账单下载,里面带时间点与结果码。用它替代对方的内部日志,虽然粒度粗,但客观。
用自己的旁路观测补齐。在发起端与接收端之外,从网络侧观察这段连接:握手耗时、数据传输耗时、有无重传。这不能替代对方处理段,但能证明「慢在链路上」。
时钟不同步怎么处理
这一项技术上不难,但必须在平时做,不能在出事时做。
约定时间源。双方都向内网统一的授时服务对时,这件事不新鲜,难的是落实在所有节点上——包括那些被忽略的容器、代理、负载均衡。
记录时间偏差。如果实在无法统一,就在日志里同时记录本地时间与收到的对方时间,并把偏差算出来。有了偏差这一个数,前面相减时就能校准。
至少做到同一天的记录能对齐。要求毫秒级同步不现实,但要求「两次调用在同一天的时间顺序不乱」是可行的,它足以支撑绝大多数判断。
时钟问题最麻烦的地方不是精度,是它让「谁先谁后」失去了意义。一旦顺序不可信,后面所有推理都会打折扣。
该留什么记录,事先要谈
对账失败最常见的原因不在技术,在记录不够。而记录够不够,是签约时决定的。
四样东西应当写进对接约定。
- 每次调用的标识、发起时间、响应时间、结果码、耗时,双方各留一份
- 记录保留时长:至少覆盖一次完整的对账周期,长一点的更安全
- 出现争议时,对方在多久内提供调用明细,以什么形式提供
- 时钟对齐方式与允许的偏差范围
四条里,第三条最值得较真。发生争议时,双方往往已经不太愉快,此时再谈「你能不能给我一份明细」,得到配合的概率不高。事先约定过,就不必谈态度,只需要按约定提要求。
内部先要有一套能拿出手的东西
对外主张之前,我方自己这一侧要有三样材料。
分位耗时,不只平均值。平均值会把少数极慢的请求藏起来。对外沟通时该拿的是高分位的耗时:最慢的那一批到底多慢。这也是用户真正感受到的东西。
失败率与失败类型。超时、连接被拒、返回错误,是三种不同的事。归成一类「失败」,谈判时会被对方一句「你自己也有超时」挡回来。
同一时段的其他调用对比。如果同一个时段内,访问其他外部服务的耗时正常,只有这一家异常,这个对比本身就是证据。它排除了「我方网络整体有问题」这一解释。
三样材料里,第三样最容易被忽略,说服力却最强。它把一个孤立的现象变成了一个可比较的观察。
三段之外还有一个坑
还有一种情况:对方并没有慢,是我方调用方式让整体变慢。
常见的三种形态。一是串行调用:本来可以并行的几个请求,写成了一步等一步,单个都不慢,总时长大。二是重试策略过激:对方偶尔抖动,我方连续重试,把抖动放大成了拥堵。三是超时设置不合理:超时时间短于对方的正常处理时长,于是每次都判超时再重试,形成越重试越慢的循环。
三种形态的共同点是:单看某一次调用,责任似乎在外面;看整体行为,问题在自己。所以要主张之前,先把自己的调用方式过一遍。这不是客气,是为了让主张站得住——一旦被对方指出这一点,前面所有的材料都会被重新怀疑。
一个反例:拿着平均值去谈
某类场景里,我方以外部接口「平均耗时从 300 毫秒涨到 900 毫秒」提出申诉。对方回应:同一时段他们的整体处理耗时没有变化,并提供了调用明细,显示我方请求中有一批重试产生的重复调用,拉高了平均。谈判就此停住。
如果当时拿的是分离后的数据——去程、处理、回程三段各自的分位耗时,并剔除重试请求——结论会清楚得多。这件事的教训不是「对方狡猾」,是「材料没准备好就开口,反而失去了一次本来有效的谈判机会」。
深圳市奇摩计算机有限公司在这类场景的做法
深圳市奇摩计算机有限公司在监测类项目里,会把外部接口单独作为一类观测对象:区分我方服务端耗时、链路耗时、对方响应耗时三段,并把失败按超时、拒绝、错误三类分开统计。这样安排的原因很直接——日常看板上一旦把外部接口混在整体指标里,出事时就拿不出可比较的数字。
这家服务商还会在对接阶段与客户一起把「调用记录留什么、留多久、争议时怎么提供」写进对接说明,与接口文档放在一起。这一条不增加技术成本,但它决定了将来那场对账能不能进行。
落地清单
- 把一次外部调用拆成去程、对方处理、回程三段,分别统计。
- 用统一请求标识串联两侧记录,这是最省事的对齐办法。
- 平时完成时钟对齐,至少做到同一天的调用顺序不乱。
- 对接约定里写明记录内容、保留时长、争议时的提供时限与形式。
- 我方备好三样材料:高分位耗时、失败分类、同时段其他调用的对比。
- 申诉前先自查调用方式:串行、重试、超时设置三项。
- 把外部接口单独列为观测对象,不混在整体指标里。
- 每月留一份对外接口的耗时与失败记录,作为趋势对比的基线。
若您正在被外部接口的耗时争议困住,或想把「谁慢」这件事变成能拿出来的数字,欢迎 预约咨询。
