2. OpenTelemetry 核心概念:Trace、Span、Metrics、Logs、Context Propagation、Baggage

在分布式系统与异步任务编排场景中,可观测性依赖于一套标准化的数据模型与传播机制。OpenTelemetry 定义了六大核心概念,它们共同构成了从数据采集、关联到分析的基础框架。理解这些概念是进行故障排查与部署调优的前提。

2.1 Trace 与 Span:请求的完整路径与工作单元

Trace 代表一个请求或事务在分布式系统中经过的完整路径。它由多个 Span 组成,每个 Span 代表路径中的一个具体工作单元(如一次 RPC 调用、一个数据库查询、一个异步任务步骤)。

Span 是 Trace 的原子构建块,包含以下关键属性:

  • Span ID:唯一标识当前 Span。
  • Trace ID:标识整个 Trace,所有相关 Span 共享此 ID。
  • Parent Span ID:指向父 Span,形成层级关系。
  • Span Name:描述操作名称(如 process_order)。
  • Start / End Timestamp:记录操作耗时。
  • Attributes:键值对元数据(如 user.id、queue.name)。
  • Status:成功或错误状态。
关键区别: Trace 是端到端的逻辑视图,Span 是每个服务或组件内的实际执行片段。在异步任务编排中,一个 Trace 可能跨越多个队列、工作线程和重试链路。

2.2 Metrics:聚合的量化指标

Metrics 提供系统在时间维度上的聚合测量,用于监控健康状态、容量规划和性能趋势。OpenTelemetry 支持三种主要 Metric 类型:

Metric 类型 说明 典型场景
Counter 单调递增的计数器,只增不减 请求总数、任务失败次数
Histogram 对观测值进行分桶统计,可计算百分位数 任务处理延迟 P50/P99
Gauge 可上下波动的瞬时值 当前队列深度、活跃工作线程数

Metrics 不包含单个请求的上下文,但可以与 Trace 通过 Exemplar 机制关联,将极端延迟的 Trace ID 嵌入到 Histogram 桶中。

2.3 Logs:结构化的事件记录

Logs 是带有时间戳的结构化或非结构化文本记录。OpenTelemetry 推动日志从纯文本向 结构化日志 演进,要求每条日志包含 timestamp、severity、body 和 attributes。

在异步任务编排中,日志必须携带 Trace ID 和 Span ID,才能实现日志与 Trace 的关联。例如:

{
  "timestamp": "2025-03-21T10:30:00.123Z",
  "severity": "ERROR",
  "body": "Task processing failed after 3 retries",
  "attributes": {
    "trace_id": "abc123def456",
    "span_id": "span789",
    "task_id": "task-001",
    "queue": "high-priority"
  }
}
最佳实践: 在异步任务框架中,使用 LogContext 或 MDC 自动注入 Trace ID,避免手动拼接。

2.4 Context Propagation:跨边界的上下文传递

Context Propagation 是 OpenTelemetry 的“神经系统”,负责将 Trace、Span、Baggage 等信息在服务之间、线程之间、异步回调之间传递。它通过 Propagator 组件实现,支持多种协议格式:

  • W3C Trace Context:标准 HTTP 头 traceparent 和 tracestate。
  • gRPC Metadata:在 gRPC 调用中传递。
  • Message Headers:在 Kafka、RabbitMQ 等消息队列中传递。
  • Thread Local / AsyncLocal:在进程内线程切换时保持上下文。

在异步任务编排中,上下文传播的常见断裂点包括:

  1. 线程池切换:任务提交到线程池后丢失父 Span 上下文。
  2. 消息队列消费:生产者与消费者之间未正确传递 Trace ID。
  3. 定时器/延迟任务:回调执行时上下文已过期。
注意: 如果上下文传播配置不当,Trace 会断裂成多个孤立片段,导致无法追踪完整请求路径。必须确保所有异步边界都显式注入和提取 Propagator。

2.5 Baggage:跨服务传递的业务上下文

Baggage 是一组键值对,随 Trace 在整个请求链路中传播。与 Span Attributes 不同,Baggage 会跨越服务边界,用于传递业务级信息(如用户 ID、实验分组、请求优先级)。

Baggage 的使用原则:

  • 轻量:只传递少量关键业务上下文,避免携带大量数据。
  • 安全:不传递敏感信息(如密码、Token),因为 Baggage 可能被中间服务记录。
  • 显式:在代码中通过 Baggage.current() 读取,通过 Baggage.builder() 设置。
// 设置 Baggage
Baggage.current().toBuilder()
    .put("user.role", "premium")
    .put("experiment.id", "exp-2025-03")
    .build()
    .makeCurrent();

// 在远端服务读取
String role = Baggage.current().getEntryValue("user.role");

2.6 六大概念关系图

下图展示了 Trace、Span、Metrics、Logs、Context Propagation 和 Baggage 之间的协作关系:

OpenTelemetry 六大核心概念关系图 OpenTelemetry 核心概念关系 Context Propagation 跨服务/线程传递上下文 Trace 端到端请求路径 Span 单个工作单元 Metrics 聚合量化指标 Logs 结构化事件记录 Baggage 业务上下文键值对 Context Propagation 是核心枢纽,负责在 Trace/Span、Metrics、Logs 和 Baggage 之间传递关联信息

2.7 概念对比与选型指南

概念 数据粒度 跨服务传播 主要用途 异步任务场景价值
Trace 请求级 是(通过 Propagator) 追踪完整请求路径 定位任务编排中的延迟瓶颈和失败环节
Span 操作级 否(仅本地) 记录单个操作耗时与状态 分析每个异步步骤的执行时间与错误
Metrics 聚合级 否(本地聚合) 监控系统健康与趋势 监控队列积压、任务吞吐量、重试率
Logs 事件级 否(但可携带 Trace ID) 记录详细事件与异常堆栈 排查任务失败的具体原因和上下文
Context Propagation 元数据 是(核心功能) 传递 Trace/Span/Baggage 确保异步链路不断裂,跨队列/线程保持关联
Baggage 业务级 是(随 Trace 传播) 传递业务上下文 传递任务优先级、用户分群,影响调度策略
选型建议: 在异步任务编排系统中,优先保证 Context Propagation 的正确配置,这是其他所有概念能够协同工作的基础。然后根据排查需求选择:定位慢任务用 Trace/Span,监控集群负载用 Metrics,深挖异常原因用 Logs。