2. Jaeger 基础回顾:Jaeger 架构与核心概念
在深入事故响应与变更窗口故障定位之前,必须牢固掌握 Jaeger 的架构组件与核心数据模型。本章将系统回顾 Jaeger 的四大核心组件(Agent、Collector、Query、UI)以及分布式追踪的两大基石:Span 与 Trace。这些知识是后续章节中分析调用链、定位性能瓶颈和根因分析的基础。
2.1 Jaeger 整体架构
Jaeger 采用模块化、可水平扩展的架构设计,主要分为客户端库(Instrumentation)、数据采集层(Agent & Collector)、存储后端(Storage Backend)以及查询与可视化层(Query & UI)。下图展示了 Jaeger 的标准部署架构与数据流。
2.2 核心组件详解
Jaeger 的每个组件在数据采集、处理、存储和查询链路中承担特定职责。下表总结了各组件的功能定位与关键配置。
| 组件 | 功能定位 | 部署模式 | 关键端口/协议 |
|---|---|---|---|
| Jaeger Agent | 本地代理,接收应用发出的 Span,批量压缩后转发给 Collector | DaemonSet(K8s)或 Sidecar | UDP 6831/6832(Thrift Compact/Binary) |
| Jaeger Collector | 接收 Agent 或应用直连的 Span,验证、索引并写入存储 | 无状态集群,水平扩展 | gRPC 14250、HTTP 14268 |
| Jaeger Query | 提供 Trace 检索 API,服务于 UI 和外部系统 | 无状态集群,水平扩展 | HTTP 16686(API + UI) |
| Jaeger UI | Web 控制台,提供 Trace 搜索、详情查看、依赖分析 | 内嵌于 Query 或独立部署 | HTTP 16686 |
| Storage Backend | 持久化存储 Span 数据 | Cassandra / Elasticsearch / Badger(测试) | 依后端而定 |
生产环境建议: 在 Kubernetes 环境中,Agent 通常以 DaemonSet 方式部署在每个节点上,或作为 Sidecar 注入到业务 Pod 中。Collector 和 Query 应配置为无状态 Deployment,并利用 HPA 进行自动扩缩容。
2.3 Span:分布式追踪的基本单元
Span 是 Jaeger 中最基本的数据单元,代表分布式系统中一个逻辑工作单元(如一次 RPC 调用、一个数据库查询、一个消息队列发送)。每个 Span 记录以下关键信息:
- 操作名称(Operation Name):描述该 Span 代表的操作,例如
HTTP POST /api/order。 - 开始时间与持续时间:精确到微秒的时间戳和耗时。
- Span 上下文(Span Context):包含 Trace ID、Span ID、Baggage 等,用于跨进程传递追踪信息。
- 标签(Tags):键值对形式的元数据,用于描述 Span 的属性(如 HTTP 状态码、错误信息、数据库语句)。
- 日志(Logs):时间戳 + 键值对,用于记录 Span 生命周期内的关键事件(如异常堆栈、缓存命中/未命中)。
- 引用关系(References):Span 之间的父子关系或跟随关系。
// 示例:一个典型的 Span 结构(JSON 表示)
{
"traceID": "abc123def456",
"spanID": "span001",
"operationName": "HTTP GET /api/users",
"startTime": 1710000000123456,
"duration": 150000, // 微秒,即 150ms
"tags": [
{"key": "http.method", "vStr": "GET"},
{"key": "http.status_code", "vType": "int64", "vInt64": 200},
{"key": "error", "vBool": false}
],
"logs": [
{
"timestamp": 1710000000123500,
"fields": [
{"key": "event", "vStr": "cache_miss"},
{"key": "cache.key", "vStr": "user:123"}
]
}
],
"references": [
{"refType": "CHILD_OF", "traceID": "abc123def456", "spanID": "parentSpan001"}
]
}
2.4 Trace:端到端请求的完整视图
Trace 是由一组具有相同 Trace ID 的 Span 构成的树状结构,完整记录了一个请求从入口到出口经过的所有服务与操作。Trace 的核心特征包括:
- 全局唯一 Trace ID:贯穿整个请求生命周期,用于关联所有 Span。
- Span 层级关系:通过
CHILD_OF和FOLLOWS_FROM引用关系构建调用树。 - 时间轴视图:在 UI 中以瀑布图(Waterfall)形式展示,直观呈现各 Span 的耗时与并行关系。
- 服务依赖图:基于 Trace 数据自动生成服务间调用拓扑。
2.5 Span 与 Trace 的关键属性对比
| 属性 | Span | Trace |
|---|---|---|
| 定义 | 单个操作单元 | 一组具有相同 Trace ID 的 Span 集合 |
| 标识 | Span ID(唯一) | Trace ID(全局唯一) |
| 结构 | 包含 Tags、Logs、References | 树状结构,由 Span 的引用关系构成 |
| 粒度 | 细粒度(一次函数调用、一次 DB 查询) | 粗粒度(一次用户请求、一次事务) |
| UI 展示 | 瀑布图中的单个条 | 完整的瀑布图 + 服务依赖图 |
| 故障定位价值 | 定位具体哪个操作耗时高或出错 | 定位故障发生在哪个服务、哪个环节 |
事故响应关键点: 在变更窗口故障定位中,我们通常先通过 Trace ID 找到异常请求的完整调用链,然后逐层检查 Span 的 Tags(如
error=true、http.status_code=500)和 Logs(如异常堆栈),快速缩小故障范围。Span 的持续时间是判断性能瓶颈的直接指标。
2.6 采样策略简介
在生产环境中,为控制存储成本,Jaeger 默认不会采集所有 Trace。理解采样策略对于事故响应至关重要——如果故障 Trace 未被采样,将无法进行事后分析。常见的采样策略包括:
- 头部采样(Head-based Sampling):在 Trace 开始时决定是否采样,策略简单但无法针对特定错误路径。
- 尾部采样(Tail-based Sampling):在 Trace 结束后根据结果(如是否包含错误)决定是否保留,更适合故障定位场景。
- 概率采样(Probabilistic Sampling):按固定百分比采样,适用于流量均匀的场景。
- 速率限制采样(Rate Limiting Sampling):每秒最多采集 N 个 Span,防止突发流量导致存储过载。
注意: 在变更窗口等高敏感时段,建议临时提高采样率或启用尾部采样,确保关键故障 Trace 不会被遗漏。同时,确保 Agent 和 Collector 的资源配置能够应对采样率提升带来的压力。