2、Jaeger基础回顾:Jaeger架构(Agent、Collector、Query、UI)、Span与Trace核心概念

在深入SLO故障排查之前,必须牢固掌握Jaeger的核心数据模型与组件架构。本章将快速梳理Span与Trace的语义关系,并拆解Agent、Collector、Query、UI四大组件的职责与数据流。

2.1 Span与Trace:分布式追踪的原子与聚合

Jaeger的数据模型基于OpenTracing标准,核心抽象只有两个:Span(跨度)和Trace(追踪)。

概念 定义 关键属性 类比
Span 一次操作调用的记录单元,包含操作名、起止时间、标签、日志和上下文。 SpanID、ParentSpanID、TraceID、OperationName、StartTime、Duration、Tags、Logs 函数调用栈中的一行
Trace 由同一个TraceID关联的一组Span,构成一次完整请求的端到端路径。 TraceID(全局唯一)、Span列表、服务拓扑 函数调用栈的完整快照
关键原则:一个Trace由且仅由一个Root Span(无父Span)和若干Child Span组成。Root Span的Duration即为该请求的总耗时,是计算SLO延迟指标的直接数据源。

2.2 Jaeger四大组件架构

Jaeger采用解耦的微服务架构,数据从应用侧到存储侧依次经过Agent、Collector,最终通过Query和UI对外暴露。下图展示了完整的组件拓扑与数据流向。

Jaeger 四大组件架构与数据流 Jaeger 四大组件架构与数据流 应用服务 (携带Jaeger SDK) Jaeger Agent (DaemonSet / Sidecar) Jaeger Collector (无状态服务) 存储后端 (Cassandra/ES/Badger) Jaeger Query (API服务) Jaeger UI (Web控制台) UDP/HTTP gRPC 异步写入 读取 JSON API 说明: Agent 通常以 DaemonSet 或 Sidecar 模式部署在应用所在节点,负责接收 Span 并批量转发。 Collector 是无状态服务,负责校验、索引和持久化 Span;Query 提供 API 供 UI 检索 Trace。

2.3 组件职责详解

2.3.1 Jaeger Agent

  • 定位:部署在应用主机上的守护进程(DaemonSet)或 Sidecar 容器。
  • 职责:接收应用 SDK 通过 UDP 或 HTTP 发送的 Span,进行批处理、压缩后通过 gRPC 转发给 Collector。
  • 关键作用:解耦应用与 Collector,避免应用直接依赖 Collector 地址;支持采样策略下发。
生产建议:Agent 与应用同节点部署,使用 localhost 通信,避免网络抖动影响 Span 上报。Agent 本身不持久化数据,重启不会丢失已转发数据。

2.3.2 Jaeger Collector

  • 定位:无状态服务,可水平扩展。
  • 职责:接收 Agent 或 SDK 直连的 Span,执行数据校验、采样决策、索引构建,并写入存储后端。
  • 关键作用:所有 Span 的唯一写入入口;支持多种存储适配器(Cassandra、Elasticsearch、Badger)。

2.3.3 Jaeger Query

  • 定位:API 服务,对外提供 REST/gRPC 接口。
  • 职责:从存储后端读取 Trace 数据,支持按 TraceID、服务名、操作名、标签、时间范围等条件检索。
  • 关键作用:SLO 故障排查时,Query 是数据检索层,直接支撑 UI 和自动化脚本。

2.3.4 Jaeger UI

  • 定位:Web 控制台,基于 Query API 构建。
  • 职责:提供 Trace 搜索、Span 详情查看、服务依赖图、火焰图、比较分析等可视化能力。
  • 关键作用:人工排查 SLO 违规时,UI 是第一现场,通过火焰图快速定位慢 Span。

2.4 Span 核心属性与 Trace 拓扑

一个完整的 Span 包含以下关键字段,这些字段在 SLO 故障排查中直接用于计算延迟和错误率:

{
  "traceID": "abc123def456",
  "spanID": "span001",
  "parentSpanID": "",          // 空表示 Root Span
  "operationName": "POST /api/order",
  "startTime": 1710000000000000,  // 微秒级时间戳
  "duration": 250000,             // 微秒,即 250ms
  "tags": {
    "http.method": "POST",
    "http.status_code": "200",
    "error": "false"
  },
  "logs": [
    { "timestamp": 1710000000050000, "fields": { "event": "cache.miss" } }
  ],
  "process": {
    "serviceName": "order-service",
    "tags": { "hostname": "pod-xyz" }
  }
}
SLO 映射:duration 字段直接对应延迟指标;tags.error 或 http.status_code >= 500 对应错误指标。Root Span 的 duration 即为端到端延迟。

2.5 Trace 拓扑与父子关系

Trace 通过 parentSpanID 字段构建树形结构。下图展示了一个典型的三层微服务调用 Trace 拓扑:

Trace 拓扑与 Span 父子关系 Trace 拓扑与 Span 父子关系 Root Span GET /api/checkout (350ms) Child Span 1 order-service: validateCart (120ms) Child Span 2 payment-service: charge (200ms) Child Span 3 inventory-service: reserve (80ms) parentSpanID parentSpanID 关键观察: Root Span 耗时 350ms,但三个 Child Span 耗时分别为 120ms、200ms、80ms,总和 400ms > 350ms。 说明存在并行调用(Child 2 和 Child 3 可能并发执行),这是分析延迟瓶颈时必须注意的拓扑特征。

2.6 组件协作流程总结

  1. 埋点:应用 SDK 在关键操作前后创建 Span,填充 TraceID、SpanID、ParentSpanID、Tags、Logs。
  2. 上报:SDK 将 Span 通过 UDP 或 HTTP 发送给同节点的 Agent。
  3. 转发:Agent 批量压缩后通过 gRPC 发送给 Collector。
  4. 存储:Collector 校验、索引后写入 存储后端(Cassandra/ES/Badger)。
  5. 检索:Query 从存储读取 Trace 数据,提供 API。
  6. 可视化:UI 调用 Query API,展示 Trace 拓扑、Span 详情、火焰图。
常见陷阱:Agent 与 Collector 之间的 gRPC 连接若中断,Span 会在 Agent 内存中缓冲(默认最多 1 秒或 1000 条),超出则丢弃。生产环境务必监控 Agent 的 jaeger_agent_collector_proxy_failures_total 指标。