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