2. 核心概念:Span、Trace、Context Propagation、Baggage,以及它们与事务边界的关系
在分布式事务与调用链的集成场景中,OpenTelemetry 提供了四个核心抽象:Span、Trace、Context Propagation 和 Baggage。理解它们各自的职责以及如何共同定义事务边界,是构建可观测中间件的基础。
2.1 Span:事务的最小工作单元
Span 是调用链中最基本的构建块,代表一个具有开始时间和结束时间的单一操作。在事务边界集成中,一个 Span 通常对应一个数据库事务、一次 RPC 调用或一个消息队列的发送/接收操作。
| Span 属性 | 说明 | 事务边界示例 |
|---|---|---|
| Span Name | 操作名称,如 INSERT orders |
标识事务内的具体 SQL 操作 |
| Span ID | 全局唯一标识符 | 用于关联事务日志与调用链 |
| Parent Span ID | 父 Span 的 ID | 表示事务嵌套关系(如子事务) |
| Start / End Timestamp | 操作起止时间 | 精确测量事务持续时间 |
| Status | OK / Error / Unset |
标记事务提交成功或回滚 |
| Attributes | 键值对元数据 | 记录事务隔离级别、影响行数等 |
关键认知: 在中间件中,一个 Span 的生命周期应当与一个本地事务的生命周期严格对齐。Span 结束时,事务要么提交(Status=OK),要么回滚(Status=Error)。
2.2 Trace:跨进程的事务链路
Trace 由一组具有相同 Trace ID 的 Span 组成,描述一个请求在分布式系统中经过的完整路径。对于事务边界而言,Trace 刻画了事务如何跨越多个服务、数据库和消息队列。
- Trace ID:贯穿整个链路的唯一标识,所有 Span 共享此 ID。
- Span 层级:通过 Parent Span ID 形成树状结构,根 Span 通常对应入口事务。
- 事务边界映射:Trace 中每个 Span 的边界,对应一个中间件组件的事务边界。
实践建议: 当 Trace 中出现 Span 状态为 Error 时,应结合事务日志判断是业务异常还是中间件事务回滚。建议在 Span Attributes 中添加
db.transaction.id 或 mq.transaction.id 属性,便于快速定位。
2.3 Context Propagation:事务边界的传递机制
Context Propagation 是 OpenTelemetry 的核心机制,负责将 Span 上下文(包括 Trace ID、Span ID、Baggage)在进程内和进程间进行传递。在事务边界集成中,它决定了事务上下文能否正确跨越中间件边界。
| 传播方式 | 适用场景 | 事务边界风险 |
|---|---|---|
| W3C TraceContext | HTTP/gRPC 请求 | Header 丢失导致链路断裂 |
| W3C Baggage | 跨服务传递业务元数据 | Baggage 过大影响性能 |
| 消息队列 Header | Kafka / RabbitMQ | 消息投递后上下文未恢复 |
| 线程局部变量 | 异步回调 / 线程池 | 线程复用导致上下文污染 |
常见陷阱: 在使用线程池执行异步事务操作时,必须显式将父线程的 Context 注入到子线程中。否则,子事务 Span 将丢失父 Trace 关联,形成“孤儿 Span”,导致事务边界无法在 Trace 中完整呈现。
2.4 Baggage:事务边界的业务上下文
Baggage 是一组随 Context 传播的键值对,用于携带与事务相关的业务元数据。与 Span Attributes 不同,Baggage 会自动跨服务传递,非常适合在事务边界传递事务 ID、用户 ID 或业务流水号。
// 设置 Baggage(Java 示例)
Baggage.current().toBuilder()
.put("transaction.id", "txn-2024-001")
.put("user.tenant", "acme-corp")
.build()
.makeCurrent();
// 在另一个服务中读取 Baggage
String txnId = Baggage.current().getEntryValue("transaction.id");
// 输出: txn-2024-001
2.5 四者与事务边界的集成关系
下图展示了 Span、Trace、Context Propagation 和 Baggage 如何共同定义并传递一个分布式事务边界:
2.6 事务边界集成要点总结
| 概念 | 事务边界角色 | 集成检查点 |
|---|---|---|
| Span | 本地事务的起止边界 | Span 开始 = 事务 begin;Span 结束 = 事务 commit/rollback |
| Trace | 分布式事务的全局路径 | 所有参与服务的 Span 共享同一 Trace ID |
| Context Propagation | 事务上下文跨进程传递 | 确保异步/消息场景下 Context 不丢失 |
| Baggage | 事务业务元数据随行 | 传递事务 ID、用户 ID 等关键标识 |
核心原则: 在中间件调用链中,事务边界 = Span 边界 + Context 传播 + Baggage 元数据。三者缺一不可,共同构成可观测的分布式事务单元。