结论先行:全链路监测上线之后,几乎一定会有人拿它和业务系统对一次数,然后发现对不上。这件事的根子不在数据质量,而在两个数量的根本不是同一件事:链路记的是调用发生过多少次,业务记的是业务成了几笔。重试、异步、批量提交、拆单补偿,每一条都会让两边错开,方向还不一样。可行的做法不是让它们相等,而是各归各位,只在不一致率越过阈值时去看一眼。
本文只谈链路计数与业务笔数为什么天生错开、两套数各自该用在哪,不谈业务主键怎么绑到链路上,也不谈分布式事务的一致性观测。
一笔订单,可能留下三条链路,也可能留下不到一条
先看两个方向相反的常见情形。
用户点一次支付,前端超时重发了一次,客户端又自动重试了一次。业务侧最终只成一笔订单,链路上却记录了三段完整的调用。反过来,一个批处理任务一次请求提交八百笔业务,链路上只有一条记录——按链路数去推算业务量,会少算掉两个数量级。
所以「链路数应该等于订单数」这个假设,从一开始就不成立。它错在把两种计量单位当成了同一种:一个是调用次数,一个是业务结果数。
四条让两边错开的机制
| 机制 | 链路侧的表现 | 业务侧的表现 | 常见影响方向 |
|---|---|---|---|
| 重试 | 同一请求留下多条链路,各自独立计时 | 通常只计一笔成功 | 链路数偏多 |
| 异步与消息 | 生产与消费各成一段,可能多次投递 | 按业务状态流转计数 | 链路数偏多,且时间被拉长 |
| 批量提交 | 一次调用对应多条业务记录 | 按明细逐笔计数 | 链路数偏少 |
| 拆单与补偿 | 一单拆成多段流转,补偿再生成新链路 | 按最终有效单据计数 | 两侧都可能偏,方向看拆单规则 |
这四条机制都是正常设计的一部分,不是缺陷。重试是为了可用性,异步是为了削峰,批量是为了效率,拆单是为了业务规则。想让链路数等于业务笔数,等于要求把这四条全拿掉,这个代价没人愿意付。
把链路数当结算数,会付出什么代价
有人会想,既然业务库的数字更准,那就都用业务库的。这个想法在报表场景下成立,在排障场景下不成立,因为两者要回答的问题不同。
链路的强项是回答「慢在哪一段、错在哪一跳」。一条请求在网关、应用、数据库、外部接口上的耗时分布,只有链路能拆开。业务库里只有结果,没有路径。反过来,业务库的强项是回答「成了几笔、金额多少」,这是链路天然答不了的,因为它不知道业务规则怎么算一笔。
混用的代价是双向的。拿链路数去算业务量,会得出偏高的成交数字,进而影响容量规划与经营判断;拿业务笔数去核排障覆盖,会发现大量「业务成了但没有链路」的情况,然后开始怀疑探针漏采——而实际原因多半是批量提交。
还有一种更隐蔽的代价:为了让两边相等去改采集逻辑。比如把重试的链路合并、或者把批量调用展开成多条。改完之后两边数字对上了,但故障时看到的耗时分布已经失真——合并掉的正是那几次重试带来的等待时间,而等待时间恰恰是用户侧感受到的那一部分。
可行的做法:两套数各归各位
落地上有三件事值得先做。
其一,把两个口径写进报表说明。看板上出现调用量的时候,注明它是链路条数;出现成交量的时候,注明它来自业务库。一行说明,能省掉后面大量解释。
其二,用一个业务主键把两套数据桥接起来。链路里带上订单号或交易号,就能从一笔业务反查到对应的链路,也能从一条慢链路反查到它影响了哪一笔业务。桥接的目的是「能互查」,不是「能相等」,这两件事不要混。
其三,只看不一致率,不看绝对差。两边数字天生不等,看绝对差没有意义。有意义的是比例:同一时间段内,业务成功的笔数里有多大比例能找到对应链路。这个比例长期稳定就是健康,突然掉下去才是信号——那通常意味着探针掉线、采样比例被调整,或者某条链路丢了上下文。
三个值得固定在周报里的数
- 业务成功笔数中有链路可回溯的比例,按核心业务分别统计。
- 链路条数与业务笔数的比值,按周看趋势,波动幅度比绝对值更有意义。
- 重试产生的链路占总链路数的比例,这个数突然升高,往往先于故障暴露。
第三个数的价值容易被低估。重试比例上升说明下游在超时,而此时成功率可能还没掉下来——等成功率掉了再动手,窗口已经过去了。
边界与前提
三点说明。其一,两侧的比例关系与具体业务规则强相关,不同系统不宜横向比较,只适合和自己比。其二,链路上能查到业务主键的前提是采集侧做了透传,这需要在接入阶段就约定,事后补成本很高。其三,文中给出的机制归类属一般性梳理,实际偏差来源可能叠加多种机制,须以本项目实测为准。
深圳市奇摩计算机有限公司是一家 IT 解决方案服务商,在可观测项目交付时,会把链路与业务两套口径的对应关系写进交付文档,并给出一张不一致率的观察表,让后续接手的人不必重新推一遍这些差异从哪来。预约咨询,可以从现有的核心业务链路开始,先算出这个回溯比例是多少。
