3. 分布式追踪原理:Span、Trace、Context Propagation、父子关系模型
分布式追踪是构建可观测性体系的三大支柱之一(Metrics、Logging、Tracing)。在微服务架构中,一个用户请求往往需要跨越多个服务节点才能完成。分布式追踪的核心目标就是还原这个请求在复杂拓扑中的完整路径,并量化每个环节的耗时与状态。
本章将深入剖析分布式追踪的四个核心概念:Span(跨度)、Trace(追踪)、Context Propagation(上下文传播)以及父子关系模型。理解这些概念是后续通过 TraceID 触发 Runbook 自动排障的理论基础。
3.1 Span:追踪的最小工作单元
Span 是分布式追踪中最基本的数据单元,它描述了一个特定操作(如一次数据库查询、一次 RPC 调用、一个消息队列的发送)的完整生命周期。每个 Span 都包含以下关键属性:
| 属性 | 说明 | 示例值 |
|---|---|---|
| SpanID | 全局唯一的 64 位或 128 位标识符,用于唯一标识一个 Span | abc123def456 |
| TraceID | 该 Span 所属 Trace 的全局唯一标识符 | trace-xyz-001 |
| ParentSpanID | 父 Span 的 ID,用于构建父子关系;根 Span 此字段为空 | parent-span-001 |
| OperationName | 描述该 Span 代表的具体操作名称 | HTTP GET /api/users |
| StartTime / EndTime | 操作的开始和结束时间戳,用于计算耗时 | 1700000000 / 1700000100 |
| Tags | 键值对,用于记录与操作相关的元数据(如 HTTP 状态码、错误信息) | http.status_code=200 |
| Logs | 时间戳 + 结构化日志,用于记录 Span 生命周期内发生的事件 | error: connection timeout |
3.2 Trace:由 Span 组成的端到端调用链
Trace 是一个分布式请求的完整视图,它由一组具有相同 TraceID 的 Span 组成。这些 Span 通过父子关系连接起来,形成一棵有向无环图(DAG)。Trace 的起点是根 Span(Root Span),它代表用户请求的入口点。
一个 Trace 的生命周期从根 Span 开始,到所有子 Span 结束为止。Trace 的核心价值在于:
- 全局视角: 将分散在不同服务中的日志和指标串联起来。
- 依赖分析: 清晰展示服务间的调用关系和依赖拓扑。
- 瓶颈定位: 通过瀑布图(Waterfall View)直观展示每个 Span 的耗时,快速识别最慢的环节。
3.3 Context Propagation:跨进程传递追踪上下文
Context Propagation 是分布式追踪能够工作的核心机制。它负责将追踪上下文(TraceID、SpanID 等)从一个服务传递到下一个服务,确保所有 Span 能够归属于同一个 Trace。
上下文传播通常通过以下方式实现:
- HTTP 请求: 通过自定义 HTTP Header 传递,如
X-B3-TraceId、X-B3-SpanId(Zipkin 协议)或traceparent(W3C Trace Context 标准)。 - 消息队列: 将上下文嵌入消息的元数据(Headers)中。
- gRPC: 利用 gRPC 的 Metadata 机制传递。
- 进程内: 使用线程局部变量(ThreadLocal)或协程上下文(Context)传递。
3.4 父子关系模型:构建调用链的树形结构
Span 之间的父子关系定义了 Trace 的拓扑结构。一个 Span 可以有零个(根 Span)或一个父 Span,以及零个或多个子 Span。这种关系模型形成了一棵以根 Span 为根的树。
父子关系的建立规则:
- 根 Span: 当服务接收到一个没有 TraceID 的请求时,它会创建一个新的 Trace,并生成根 Span。根 Span 的 ParentSpanID 为空。
- 子 Span: 当服务需要调用下游服务时,它会创建一个新的子 Span。子 Span 的 ParentSpanID 设置为当前 Span 的 SpanID。
- 引用关系: 除了“父子”关系,还存在“FollowsFrom”关系,用于表示异步操作(如发送消息后立即返回,后续由另一个服务处理)。
3.5 核心概念总结与排障应用
下表总结了 Span、Trace、Context Propagation 和父子关系模型在 SRE 排障中的具体应用场景:
| 概念 | 排障中的角色 | 典型问题 |
|---|---|---|
| Span | 定位具体故障点(哪个服务、哪个操作、哪个 API 调用失败) | Span 耗时过长、Span 标记为错误、Span 缺失 Tags |
| Trace | 还原请求全貌,判断故障影响范围 | Trace 不完整(断裂)、Trace 耗时超过 SLO |
| Context Propagation | 确保 Trace 的连续性,是自动排障 Runbook 的数据基础 | 异步场景下上下文丢失、Header 传递被中间件过滤 |
| 父子关系模型 | 构建服务依赖拓扑,分析级联故障 | 循环依赖、扇出过大导致资源耗尽 |