2. 核心概念:Trace、Span、SpanContext、Baggage、采样率、传播机制
分布式追踪并非单一技术,而是一套由多个核心概念构成的协作模型。理解这些概念是部署与配置追踪系统的基础。本节将逐一拆解 Trace、Span、SpanContext、Baggage、采样率与传播机制,并阐明它们之间的层级关系。
2.1 概念全景图
下图展示了分布式追踪中六个核心概念之间的逻辑关系与数据流向:
2.2 Trace(追踪)
Trace 代表一次完整的请求或事务在分布式系统中的端到端执行路径。它由一组具有相同 TraceID 的 Span 组成,逻辑上构成一个有向无环图(DAG)。
- 唯一标识:每个 Trace 拥有全局唯一的
TraceID(通常为 16 字节或 128 位随机数)。 - 生命周期:从客户端发起请求开始,到最终响应返回结束。
- 可视化:在 Jaeger、Zipkin 等 UI 中,Trace 展示为瀑布图或时间线。
实践要点:Trace 的根 Span(Root Span)通常由入口网关或 API 网关创建。确保网关层正确生成 TraceID,否则后续服务无法关联到同一 Trace。
2.3 Span(跨度)
Span 是追踪的最小工作单元,代表一个服务内部或一次远程调用中具有开始时间和结束时间的操作片段。每个 Span 记录以下关键信息:
| 字段 | 说明 | 示例 |
|---|---|---|
| SpanID | 当前 Span 的唯一标识(8 字节随机数) | a1b2c3d4e5f6g7h8 |
| ParentSpanID | 父 Span 的 ID,用于构建父子层级 | 9i8u7y6t5r4e3w2q |
| OperationName | 操作名称(如 HTTP 方法 + 路径) | GET /api/orders |
| StartTime / EndTime | 操作开始与结束的时间戳 | 1710000000000 |
| Tags / Attributes | 键值对元数据(如 HTTP 状态码、错误信息) | http.status_code=200 |
| Events / Logs | Span 生命周期内的结构化日志 | cache.miss |
Span 关系类型:
- ChildOf:子 Span 依赖于父 Span(最常见,如 RPC 调用)。
- FollowsFrom:子 Span 在父 Span 之后异步执行(如消息队列消费)。
2.4 SpanContext(跨度上下文)
SpanContext 是跨进程传递追踪状态的核心载体。它包含以下不可变信息:
- TraceID:全局追踪标识。
- SpanID:当前 Span 标识。
- TraceFlags:追踪标志位(如是否被采样)。
- TraceState:W3C TraceContext 定义的供应商无关键值对列表。
- Baggage:用户自定义的透传数据(见 2.5 节)。
SpanContext 通过传播机制(见 2.7 节)在服务之间传递,确保下游服务能够将新创建的 Span 关联到正确的 Trace 树中。
2.5 Baggage(行李)
Baggage 是一组随 SpanContext 跨服务传播的键值对(Key-Value),用于携带业务上下文信息,例如:
- 用户 ID、会话 ID
- 请求来源(如
source=web) - A/B 测试分组标识
重要警告:Baggage 会随每个请求传播到所有下游服务,切勿将敏感信息(密码、、PII)放入 Baggage。同时,Baggage 数据量应保持极小(建议不超过 10 对键值对),否则会显著增加网络开销。
2.6 采样率(Sampling)
在高并发系统中,为每个请求生成完整 Trace 会产生巨大的存储与性能开销。采样率 控制哪些请求被记录和上报。常见采样策略如下:
| 策略 | 原理 | 适用场景 |
|---|---|---|
| 头部采样(Head-Based) | 在请求入口处决定是否采样,后续服务遵循同一决策 | 低延迟、高吞吐场景(默认策略) |
| 尾部采样(Tail-Based) | 先记录所有 Span,事后根据规则(如错误率、延迟)决定保留哪些 Trace | 需要完整错误分析、慢请求诊断 |
| 概率采样 | 按固定百分比(如 10%)随机采样 | 流量均匀、无需精细控制 |
| 速率限制采样 | 每秒最多采样 N 个 Trace | 防止突发流量导致后端过载 |
推荐实践:生产环境建议使用 头部采样 + 概率采样 组合,例如设置 5% 基础采样率,同时通过尾部采样保留所有错误 Trace。Jaeger 和 OpenTelemetry Collector 均支持此类混合策略。
2.7 传播机制(Propagation)
传播机制 定义了 SpanContext 如何在服务之间传递。主流协议包括:
- W3C TraceContext(推荐):使用
traceparent和tracestate两个 HTTP Header,是 OpenTelemetry 默认标准。 - Zipkin B3:使用
X-B3-TraceId、X-B3-SpanId、X-B3-ParentSpanId、X-B3-Sampled四个 Header。 - Jaeger:使用
uber-trace-id单个 Header 编码所有信息。 - gRPC Metadata:在 gRPC 调用中通过 Metadata 传递。
- 消息队列:通过消息头(如 Kafka Headers、RabbitMQ Headers)传递。
传播机制对比
| 协议 | Header 数量 | 标准化程度 | 推荐度 |
|---|---|---|---|
| W3C TraceContext | 2 | W3C 标准 | ★★★★★ |
| Zipkin B3 | 4 | 事实标准 | ★★★★☆ |
| Jaeger | 1 | 供应商特定 | ★★★☆☆ |
传播机制配置示例(OpenTelemetry SDK):
// 使用 W3C TraceContext 传播器
from opentelemetry import propagate
from opentelemetry.propagators.tracecontext import TraceContextTextMapPropagator
propagate.set_global_textmap(TraceContextTextMapPropagator())
// 同时支持 W3C 和 B3(多传播器)
from opentelemetry.propagators.composite import CompositePropagator
from opentelemetry.propagators.b3 import B3Propagator
propagate.set_global_textmap(
CompositePropagator([
TraceContextTextMapPropagator(),
B3Propagator(),
])
)
2.8 核心概念总结表
| 概念 | 作用 | 关键属性 | 跨进程传递 |
|---|---|---|---|
| Trace | 端到端请求路径 | TraceID | 否(逻辑容器) |
| Span | 单个操作单元 | SpanID, ParentSpanID, 时间戳 | 否(本地对象) |
| SpanContext | 跨进程传递的追踪状态 | TraceID, SpanID, TraceFlags | 是(核心载体) |
| Baggage | 业务上下文透传 | 键值对集合 | 是(随 SpanContext) |
| 采样率 | 控制数据采集量 | 采样策略、概率值 | 部分(头部采样决策可传递) |
| 传播机制 | 定义 SpanContext 的序列化与反序列化 | 协议类型、Header 格式 | 是(传输层实现) |