审计链路核心概念:Trace、Span、Context 传播
好,咱们正式开始聊链路审计的核心概念。
说实话,刚开始接触分布式链路追踪的时候,我也有点晕。Trace 是什么?Span 又是什么?Context 怎么传的?一堆术语砸过来。后来在项目里真正踩过坑,才把这些东西串起来。
Trace:一次请求的完整旅程
Trace,翻译过来就是“追踪”。你可以把它想象成一次请求的完整生命周期。比如,你下单买了个东西,这个请求从前端打到后端,后端又调了订单服务、库存服务、支付服务——这一整条调用链,就是一个 Trace。
每个 Trace 都有一个全局唯一的 Trace ID。我习惯把它叫做“身份证号”。有了这个 ID,你就能把一次请求经过的所有服务串起来。
举个例子:
| 属性 | 说明 |
|---|---|
| Trace ID | 全局唯一标识,贯穿整个调用链 |
| 开始时间 | 入口请求发起的时间 |
| 结束时间 | 整个链路结束的时间 |
| 涉及服务 | 请求经过的所有服务节点 |
Span:链路中的最小工作单元
Trace 是由一个个 Span 组成的。Span 就是一次服务调用的“快照”。比如订单服务调库存服务,这就是一个 Span。这个 Span 记录了谁调了谁、花了多长时间、结果如何。
我记得有一次排查线上慢接口,就是靠着 Span 的耗时数据,发现某个数据库查询占了 80% 的时间。没有 Span,你只能瞎猜。
每个 Span 都有自己的 Span ID,同时会记录父 Span ID。这样就能构建出调用关系的树形结构。
{
"traceId": "abc123",
"spanId": "span001",
"parentSpanId": "span000",
"serviceName": "order-service",
"operationName": "checkStock",
"startTime": 1700000000000,
"endTime": 1700000000100,
"tags": {
"http.status_code": 200,
"error": false
}
}
Span 的状态字段挺关键的。我一般关注这几个:
- operationName:操作名称,比如“查询库存”
- startTime / endTime:开始和结束时间,用来算耗时
- tags:自定义标签,比如 HTTP 状态码、错误信息
- logs:日志事件,比如异常堆栈
Context 传播:串联一切的隐形线索
光有 Trace ID 和 Span ID 还不够。你得想办法把这些 ID 从一个服务传到下一个服务。这就是 Context 传播。
说白了,Context 就是一组键值对,里面装着 Trace ID、Span ID 这些信息。每次发起远程调用(HTTP、gRPC、RPC),都得把这些信息塞进请求头里,传给下游服务。
为什么必须传?你想想看,如果订单服务调库存服务时,库存服务不知道当前 Trace ID 是多少,那它创建的 Span 就断开了,根本连不到同一个 Trace 上。
三者关系:一图胜千言
讲道理,文字说再多不如一张图清楚。下面这个结构图,把 Trace、Span 和 Context 传播的关系画明白了。
关键术语速查表
| 术语 | 英文 | 一句话解释 |
|---|---|---|
| 追踪 | Trace | 一次请求的完整调用链 |
| 跨度 | Span | 一次服务调用的快照 |
| 上下文 | Context | 传递 Trace ID 等信息的载体 |
| 父跨度 | Parent Span | 调用当前服务的上一个 Span |
| 传播 | Propagation | Context 在服务间的传递过程 |
核心要点回顾
- Trace 是整体,Span 是零件。一个 Trace 包含多个 Span。
- Span 记录了调用关系、耗时、状态,是排查问题的关键。
- Context 必须在服务间显式传播,否则链路会断掉。
- 父 Span ID 是构建调用树的核心,没有它 Trace 就变成了一堆散沙。
这三个概念是整门课的基石。理解透了,后面讲采集、采样、存储、分析都会轻松很多。你想想看,连 Span 是什么都搞不清,怎么去做审计分析?对吧。