1. 分布式追踪基础:分布式系统挑战、追踪核心概念与标准

1.1 分布式系统的可观测性挑战

在单体架构中,一次用户请求的完整调用链路通常运行在单一进程内,通过日志和堆栈即可定位问题。然而,当系统拆分为数十甚至数百个微服务后,一次请求会穿越多个服务、数据库、消息队列与第三方 API,传统的监控手段面临三大核心挑战:

  • 调用链断裂:日志分散在不同服务的主机上,缺乏全局 Request ID 串联,无法还原请求的完整路径。
  • 性能瓶颈定位困难:只知道整体响应时间变慢,但无法判断是哪个服务、哪个数据库查询或哪个网络跳转导致的延迟。
  • 故障根因分析低效:一个服务异常可能引发下游雪崩,运维人员需要手动关联多个监控系统的告警,排查周期长。
关键认知: 分布式追踪(Distributed Tracing)正是为解决上述挑战而生。它通过为每个请求注入全局唯一的 Trace ID,在服务间传递上下文,从而重建完整的请求调用拓扑与时间线。

1.2 追踪核心概念:Trace 与 Span

分布式追踪的数据模型围绕两个核心抽象构建:Trace(追踪)和 Span(跨度)。

概念 定义 关键属性
Trace 代表一次完整的请求或事务在分布式系统中的全生命周期。由一组具有相同 Trace ID 的 Span 组成。 Trace ID(全局唯一)、Span 集合、开始时间、结束时间
Span Trace 中的最小工作单元,代表一个服务内部或服务间的一次具体操作(如 HTTP 请求、数据库查询)。 Span ID、Parent Span ID、操作名称、开始/结束时间戳、标签(Tags)、日志(Logs)

Span 之间通过 Parent-Child 关系 形成树状结构。一个 Span 可以包含多个子 Span,子 Span 代表更细粒度的操作。例如,一个“下单” Trace 可能包含“网关路由”、“订单服务校验库存”、“支付服务扣款”等多个 Span。

实践要点: 在 Jaeger UI 中,Trace 视图通常以瀑布图(Waterfall Diagram)展示,每个 Span 按时间轴排列,父 Span 包裹子 Span 的时间范围。这是定位延迟瓶颈最直观的界面。
Trace 与 Span 树状结构示例 Trace ID: abc123 — 根 Span: /checkout (总耗时 320ms) Span A: 订单服务 — 校验库存 (120ms) Span B: 支付服务 — 扣款 (150ms) Span B-1: 支付服务 — 调用第三方支付网关 (100ms) Span C: 通知服务 — 发送确认邮件 (50ms) 说明:每个 Span 记录开始/结束时间戳,父 Span 的时间范围必须包含所有子 Span 的时间范围。

1.3 追踪标准演进:从 OpenTracing 到 OpenTelemetry

早期分布式追踪领域存在多种私有协议(如 Zipkin、Jaeger 原生格式),导致厂商锁定与集成成本高。为了解决互操作性问题,社区先后推出了两个关键标准:

1.3.1 OpenTracing(已进入维护阶段)

OpenTracing 是 CNCF 孵化的第一个分布式追踪 API 标准。它定义了一套与厂商无关的 API,允许开发者使用同一套代码接入不同的追踪后端(Jaeger、Zipkin、LightStep 等)。其核心接口包括:

  • Tracer:创建 Span 的入口。
  • Span:表示一个工作单元,支持设置 Tags、Logs 和 Baggage。
  • SpanContext:携带 Trace ID、Span ID 以及 Baggage 数据,用于跨进程传递。
// OpenTracing 示例:创建子 Span
Span parentSpan = tracer.buildSpan("parent-operation").start();
Span childSpan = tracer.buildSpan("child-operation")
    .asChildOf(parentSpan)
    .start();
// 执行操作...
childSpan.finish();
parentSpan.finish();

1.3.2 OpenTelemetry(当前主流标准)

OpenTelemetry(简称 OTel)由 OpenTracing 与 OpenCensus 合并而来,已成为云原生计算基金会(CNCF)的毕业项目。它统一了追踪、指标和日志三大信号的数据采集规范,提供以下关键能力:

特性 OpenTracing OpenTelemetry
信号范围 仅追踪(Tracing) 追踪 + 指标 + 日志(统一 SDK)
数据模型 Span 为主 Span + Metrics + Logs 统一模型
上下文传播 自定义格式 W3C TraceContext 标准
SDK 成熟度 维护模式,不再新增功能 活跃开发,主流语言支持完善
与 Jaeger 集成 通过 Jaeger 客户端直接上报 通过 OTel Collector 转发至 Jaeger
迁移建议: 新项目应直接采用 OpenTelemetry SDK 进行埋点。对于已使用 OpenTracing 的老项目,Jaeger 仍兼容接收 OpenTracing 格式数据,但建议逐步迁移至 OTel 以获取更完整的可观测性能力。

1.4 OpenTelemetry 核心架构与 Jaeger 的关系

OpenTelemetry 采用“采集-处理-导出”的管道架构。在 Jaeger 生态中,OTel Collector 通常作为数据采集与预处理层,将处理后的 Span 数据发送至 Jaeger 后端存储与查询。

OpenTelemetry + Jaeger 集成架构 应用服务 A 应用服务 B 应用服务 C OTel SDK 埋点 OTel Collector 批处理 / 采样 / 过滤 Jaeger Collector 存储 / 索引 Jaeger Query API / UI 展示 说明:应用服务通过 OTel SDK 生成 Span,经 OTel Collector 统一处理后转发至 Jaeger 后端进行存储与查询。

1.5 本章小结

  • 分布式系统面临调用链断裂、瓶颈定位难、根因分析低效三大可观测性挑战。
  • Trace 代表一次完整请求,Span 代表请求中的单个操作单元,Span 之间通过 Parent-Child 关系形成树状结构。
  • OpenTracing 定义了厂商中立的追踪 API,但已进入维护阶段;OpenTelemetry 统一了追踪、指标、日志三大信号,是当前及未来的标准。
  • Jaeger 作为 CNCF 毕业的分布式追踪系统,原生支持 OpenTelemetry 数据格式,通过 OTel Collector 实现无缝集成。