3. 分布式追踪基础:Trace、Span、SpanContext、TraceId、SpanId 的定义与关系
分布式追踪是平台工程中观测性(Observability)的三大支柱之一,也是值班台服务目录实现调用链可视化的核心数据模型。理解 Trace、Span、SpanContext、TraceId、SpanId 这五个基本概念及其关系,是设计分布式追踪服务目录的前提。
3.1 核心概念定义
分布式追踪的数据模型源自 Google Dapper ,并被 OpenTelemetry、Jaeger、Zipkin 等主流实现继承。下表列出了五个核心概念的定义与职责:
| 概念 | 英文 | 定义 | 类比(快递物流) |
|---|---|---|---|
| Trace | Trace | 一次完整请求在分布式系统中经过的所有服务、组件和操作的全局记录,由多个 Span 组成的有向无环图(DAG)。 | 一个快递从寄件到签收的完整物流轨迹。 |
| Span | Span | Trace 中的一个工作单元,代表一个服务或组件内的一次具体操作(如 RPC 调用、数据库查询、消息发送)。每个 Span 记录开始时间、结束时间、状态和标签。 | 物流轨迹中的单个节点操作,如“到达 A”、“离开 A”。 |
| SpanContext | SpanContext | 跨进程传递的追踪上下文,包含 TraceId、SpanId 以及可选的 Baggage(业务透传数据)。它是分布式传播的载体。 | 快递面单上的运单号、当前站点编号和备注信息。 |
| TraceId | TraceId | 全局唯一的 128 位或 64 位标识符,用于关联属于同一次请求的所有 Span。一个 Trace 有且只有一个 TraceId。 | 快递运单号,整个物流过程唯一不变。 |
| SpanId | SpanId | Span 的唯一标识符,64 位整数。用于在 Trace 内唯一标识一个工作单元。 | 物流节点操作流水号,每个操作步骤唯一。 |
3.2 概念关系:从 Trace 到 Span 的树形结构
Trace 与 Span 之间是 1:N 的包含关系。一个 Trace 包含多个 Span,这些 Span 通过 ParentSpanId 形成树形或 DAG 结构。根 Span(Root Span)没有父 Span,代表请求的入口点。
下图展示了 Trace 与 Span 的树形关系,以及 TraceId、SpanId、ParentSpanId 如何串联整个调用链:
3.3 SpanContext:跨进程传播的纽带
SpanContext 是分布式追踪中实现跨进程上下文传播的关键数据结构。当服务 A 调用服务 B 时,服务 A 将当前 Span 的 SpanContext 序列化后注入到 RPC 请求头(如 HTTP Header、gRPC Metadata)中,服务 B 从请求头中提取 SpanContext,并据此创建子 Span。
SpanContext 的核心组成:
- TraceId:全局唯一,标识整个请求链路。
- SpanId:当前 Span 的 ID,用于在接收端创建子 Span 时作为 ParentSpanId。
- TraceFlags:追踪选项,如是否采样(Sampled Flag)。
- TraceState:厂商特定的追踪状态键值对,用于跨不同追踪系统的兼容。
- Baggage(可选):用户自定义的业务上下文键值对,随请求透传。
3.4 TraceId 与 SpanId 的生成与生命周期
TraceId 和 SpanId 的生成策略直接影响追踪系统的性能和正确性。下表对比了两种常见 ID 生成方式:
| 属性 | TraceId | SpanId |
|---|---|---|
| 长度 | 128 bit(推荐)或 64 bit | 64 bit |
| 生成时机 | 请求入口(Root Span 创建时) | 每个 Span 创建时 |
| 生成算法 | 随机数 + 时间戳(如 UUID v4) | 随机数或递增计数器 |
| 唯一性要求 | 全局唯一,跨服务、跨集群 | 在 Trace 内唯一即可 |
| 生命周期 | 从请求开始到结束 | Span 创建到完成 |
| 传播范围 | 整个 Trace 的所有 Span | 当前 Span 及其子 Span 的 ParentSpanId |
3.5 从概念到服务目录的映射
在值班台分布式追踪服务目录设计中,上述概念直接映射为目录的数据模型和查询能力:
- Trace → 服务目录中的“调用链”实体,包含开始时间、结束时间、总耗时、状态。
- Span → 服务目录中的“调用节点”实体,包含服务名、操作名、耗时、标签、事件。
- SpanContext → 服务目录的“上下文关联”机制,用于跨服务目录条目关联。
- TraceId → 服务目录的“全局追踪 ID”索引字段,支持按 TraceId 精确查询。
- SpanId → 服务目录的“节点 ID”字段,支持按 SpanId 定位具体操作。
下图展示了从原始追踪数据到服务目录实体的映射流程:
3.6 常见误区与避坑指南
常见误区 2: 将 SpanId 设计为全局唯一。SpanId 只需在 Trace 内唯一,全局唯一会增加生成开销且无实际收益。
常见误区 3: 在服务目录中只存储 TraceId 和 SpanId,不存储 ParentSpanId。这会导致无法重建调用链拓扑,只能展示平铺的 Span 列表。
3.7 本章小结
Trace、Span、SpanContext、TraceId、SpanId 构成了分布式追踪的五大基础概念。Trace 是请求的全局视图,Span 是 Trace 中的工作单元,SpanContext 是跨进程传播的上下文载体,TraceId 和 SpanId 分别是 Trace 和 Span 的唯一标识。在值班台服务目录设计中,这些概念直接决定了目录的数据模型、索引策略和调用链还原能力。掌握这些基础,是后续设计服务目录存储、查询和可视化功能的前提。