2、Jaeger链路追踪原理:Jaeger架构、Span与Trace模型、采样策略

本章深入剖析Jaeger的核心运行机制,涵盖组件架构、数据模型与采样策略。理解这些原理是后续进行SLO误差预算验证与链路诊断的基础。

2.1 Jaeger整体架构

Jaeger采用模块化、可水平扩展的架构设计,主要包含以下核心组件:Agent(代理)、Collector(收集器)、Query(查询服务)与UI(用户界面)。各组件协同工作,完成链路数据的采集、传输、存储与检索。

Jaeger 核心架构组件与数据流 应用服务 (Service A) 业务逻辑 Jaeger Client (SDK) 生成 Span / Trace Jaeger Agent UDP 接收器 批处理 / 压缩 边车进程 / DaemonSet Jaeger Collector gRPC / HTTP 接收 验证 / 索引 / 存储 无状态,可水平扩展 存储后端 Cassandra / Elasticsearch / Badger Jaeger Query Service + Jaeger UI API 查询 / 链路检索 / 依赖分析 UDP (Thrift) gRPC (Protobuf) 写入 读取 架构要点 • Agent 作为边车进程部署,与应用同生命周期,负责本地 Span 收集与批量上报。 • Collector 是无状态服务,接收数据后校验、建立索引并写入存储后端,是吞吐瓶颈的关键观测点。

2.2 Span 与 Trace 模型

Jaeger的数据模型基于OpenTracing标准,核心概念为Span(跨度)与Trace(追踪)。一个Trace代表一次完整的请求或事务,由一组具有因果关系的Span组成的有向无环图(DAG)。

2.2.1 Span 结构

每个Span记录一个操作单元,包含以下关键字段:

字段 说明 示例
operationName 操作名称,如HTTP方法、RPC调用名 GET /api/users
spanId 当前Span的唯一标识(64位整数) abc123def456
traceId 所属Trace的唯一标识(128位整数) trace_001
parentSpanId 父Span的ID,根Span此字段为空 parent_span_01
startTime / duration 开始时间戳与持续时长(微秒) 1680000000 / 15000
tags 键值对标签,用于附加元数据 http.status_code=200
logs 带时间戳的日志事件 error: connection timeout

2.2.2 Trace 与 Span 关系

下图展示了一个典型微服务请求的Trace结构,包含4个Span,清晰呈现了调用链与父子关系:

Trace 结构示例:用户查询请求 T0 T1 Span A: /api/order (根Span, traceId=xyz) 700ms Span B: auth.verifyToken (父: A) 500ms Span C: db.queryUser (父: B) 300ms Span D: cache.getOrder (父: A) 250ms Trace 关键特征 • 同一 Trace 内所有 Span 共享相同的 traceId。 • 根 Span 的 parentSpanId 为空,其 duration 代表请求总耗时。 • 通过 parentSpanId 可重建完整的调用拓扑,用于识别瓶颈与异常传播。

2.3 采样策略

在高并发生产环境中,为每个请求生成完整Trace会产生巨大的存储与网络开销。采样策略用于控制采集链路数据的比例,在数据完整性与资源成本之间取得平衡。Jaeger支持多种采样模式:

采样策略 工作原理 适用场景 注意事项
恒定采样 固定采样率(0~1),如0.1表示采集10% 低流量环境、调试阶段 高流量下存储压力大
速率限制采样 每秒最多采集N个Span 控制峰值写入速率 低流量时可能采集不足
概率采样 基于traceId哈希,按概率决定是否采集 生产环境默认推荐 需保证哈希均匀分布
自适应采样 根据流量动态调整采样率,优先保留慢请求 SLO监控、误差预算验证 需Collector端配置
SRE 实践提示: 在SLO误差预算验证场景中,推荐使用自适应采样或概率采样。自适应采样能自动增加慢请求的采样概率,确保异常链路不被遗漏,这对于准确计算误差预算消耗至关重要。

2.3.1 采样决策流程

采样决策通常在客户端SDK中完成,流程如下:

  1. 获取采样配置: 客户端启动时从Agent或远程配置中心拉取采样策略。
  2. 计算采样决策: 对于每个新Trace,根据策略类型计算是否采样。概率采样使用 traceId % 采样分母 判断。
  3. 传播采样标记: 将采样决策(sampled=true/false)通过请求头传播给下游服务,确保同一Trace的所有Span采样状态一致。
  4. 上报Span: 仅当sampled=true时,Span数据才会被发送到Agent。
关键参数: 采样率直接影响误差预算台账的数据量。采样率过低可能导致关键SLO违规事件未被记录;采样率过高则增加存储成本。建议初始设置为 0.1(10%),并根据实际数据量与SLO目标逐步调整。

2.3.2 采样策略配置示例

以下为Jaeger客户端(Go语言)配置概率采样的代码示例:

// 使用概率采样,采样率为 0.1(10%)
cfg := &jaegerconfig.Configuration{
  Sampler: &jaegerconfig.SamplerConfig{
    Type:  jaeger.SamplerTypeProbabilistic,
    Param: 0.1,
  },
  // ... 其他配置
}

// 创建 Tracer
tracer, closer, err := cfg.NewTracer()
if err != nil {
  log.Fatal("无法创建 Jaeger Tracer:", err)
}
defer closer.Close()

通过理解Jaeger的架构、数据模型与采样策略,SRE工程师能够精准配置链路采集,为后续的SLO误差预算验证提供可靠的数据基础。