3. 分布式追踪核心概念:Trace、Span、SpanContext、Baggage
在分布式系统中,一个用户请求往往需要跨越多个微服务、数据库、消息队列和第三方 API 才能完成。要快速定位这类请求的故障根因,必须理解分布式追踪的四个核心抽象:Trace、Span、SpanContext 和 Baggage。它们是 Jaeger 等追踪系统的数据模型基石,也是事故响应时解读调用链的“语言”。
3.1 Trace:端到端的请求全景图
Trace(追踪)代表一个完整的、端到端的请求在分布式系统中的执行路径。它由一组具有相同 Trace ID 的 Span 组成,逻辑上描述了一次事务从入口到出口的全过程。
- 唯一标识:每个 Trace 由一个全局唯一的
TraceID标识(通常为 128 位或 64 位整数)。 - 生命周期:从客户端发起请求开始,到最终响应返回结束。
- 故障定位价值:在事故响应中,通过 Trace 可以快速判断故障影响范围——是整个 Trace 超时,还是某个下游服务导致整体延迟飙升。
3.2 Span:追踪的最小工作单元
Span(跨度)是分布式追踪中描述一次具体操作的最小工作单元。每个 Span 代表一个服务内部完成的单一操作,例如一次数据库查询、一次 RPC 调用或一段业务逻辑处理。
| Span 属性 | 说明 | 故障定位用途 |
|---|---|---|
| OperationName | 操作名称,如 HTTP POST /api/order |
快速识别操作类型 |
| SpanID | 当前 Span 的唯一标识 | 区分同一 Trace 内的不同操作 |
| ParentSpanID | 父 Span 的 ID,用于构建调用层级 | 还原调用链上下游关系 |
| StartTime / Duration | 开始时间戳和持续时长 | 计算延迟、发现慢操作 |
| Tags | 键值对元数据,如 http.status_code=500 |
记录错误码、异常类型等关键信号 |
| Logs | 时间戳 + 结构化日志事件 | 记录异常堆栈、关键变量值 |
error=true 或 http.status_code >= 500 的 Span。这些是根因定位的“第一现场”。
3.3 SpanContext:跨进程的追踪上下文
SpanContext(跨度上下文)是跨进程传递追踪信息的载体。当服务 A 调用服务 B 时,必须将当前 Trace 的上下文信息通过 RPC 头部或消息队列属性传递给下游,否则两个服务之间的 Span 将无法关联到同一个 Trace。
SpanContext 包含以下核心数据:
- TraceID:全局唯一追踪 ID。
- SpanID:当前 Span 的 ID。
- Baggage:用户自定义的键值对(见 3.4 节)。
- TraceFlags:追踪标志位,如是否采样。
uber-trace-id 或 traceparent 头部。
3.4 Baggage:跨服务传递的上下文数据
Baggage(行李)是 SpanContext 中一组用户自定义的键值对,会随着 Trace 的传播自动传递到所有下游 Span。与 Tags 不同,Baggage 是跨进程传递的,而 Tags 仅存在于当前 Span 所在进程。
| 特性 | Tags | Baggage |
|---|---|---|
| 作用域 | 当前 Span 所在进程 | 整个 Trace 的所有 Span |
| 传递方式 | 不跨进程 | 通过 SpanContext 跨进程传递 |
| 典型用途 | 记录错误码、延迟、SQL 语句 | 传递用户 ID、请求来源、A/B 测试标签 |
| 性能影响 | 低(仅本地存储) | 中(序列化到每个 RPC 头部) |
| 事故响应价值 | 定位具体错误原因 | 关联用户维度、灰度版本等业务上下文 |
deploy.version 或 feature.flag 可以快速判断该请求是否命中刚上线的灰度版本,从而缩小根因范围。
3.5 核心概念关系总结
四个核心概念的关系可以概括为:一个 Trace 包含多个 Span,每个 Span 携带 SpanContext,SpanContext 中可附加 Baggage。在 Jaeger UI 中,Trace 以瀑布图形式展示,每个横条代表一个 Span,横条长度表示 Duration,颜色表示服务或状态。
3.6 事故响应中的概念应用
在变更窗口事故响应场景中,理解这四个概念能帮助 SRE 快速建立排查路径:
- 通过 TraceID 锁定故障请求:从告警或日志中提取 TraceID,在 Jaeger 中打开完整 Trace 瀑布图。
- 扫描 Span 列表:按 Duration 降序排列,找到耗时最长的 Span;检查 Tags 中是否有
error=true或异常状态码。 - 检查 SpanContext 传递:如果 Trace 不完整,确认上下游服务是否正确传递了
uber-trace-id头部。 - 利用 Baggage 做业务关联:如果 Baggage 中携带了
deploy.version,对比正常 Trace 与故障 Trace 的版本差异。