2. Jaeger 架构深度解析:核心组件与数据流

Jaeger 作为云原生链路追踪的事实标准,其架构设计遵循“采集-缓冲-处理-存储-查询”的经典管道模式。本章深入拆解 jaeger-agent、jaeger-collector、jaeger-query、jaeger-ingester 四大核心组件,并完整呈现一条 Span 从产生到可视化的全链路数据流。

2.1 整体架构总览

下图展示了 Jaeger 的典型部署拓扑,包含客户端 SDK、Agent、Collector、Ingester、存储后端及 Query 服务之间的数据流向。

Jaeger 核心组件与数据流架构图 Jaeger 核心组件与数据流架构 应用服务 (SDK 埋点) 生成 Span / Trace jaeger-agent 本地代理 / 侧边 批量压缩转发 jaeger-collector 无状态接收 校验/采样/存储 UDP/gRPC gRPC jaeger-ingester 从 Kafka 消费 批量写入存储 Apache Kafka 缓冲 / 解耦 持久化消息队列 Span 写入 消费 存储后端 Elasticsearch Cassandra / Badger 直写(无 Kafka) jaeger-query API / UI 服务 读取存储 / 聚合 读取 HTTP/gRPC 数据流说明 实线:主数据流 虚线:可选直写 Agent 为 DaemonSet
架构要点:Agent 作为 Sidecar 或 DaemonSet 部署,与业务进程同节点,避免网络抖动;Collector 为无状态水平扩展层;Kafka 作为可选的缓冲层,用于应对流量洪峰;Ingester 专门消费 Kafka 并批量写入存储;Query 提供统一的检索 API 和 UI。

2.2 核心组件详解

2.2.1 jaeger-agent:本地代理与数据缓冲

Agent 是部署在每台宿主机或 Pod 中的轻量级守护进程,主要职责包括:

  • 接收 Span:通过 UDP(Thrift 协议)或 gRPC 接收来自 SDK 的 Span 数据。
  • 数据压缩与批处理:将多个 Span 合并为更大的批次,减少网络连接次数。
  • 服务发现:自动发现 Collector 集群地址,实现负载均衡。
  • 自适应采样:配合 Collector 下发的采样策略,在本地执行概率采样或速率限制。
通信方式协议适用场景性能特征
UDP (Thrift)Compact / Binary高吞吐、低延迟、可容忍少量丢包极低 CPU 开销,无连接管理
gRPCProtobuf需要可靠传输、大 Span 或 TLS 加密稍高 CPU,支持流式传输
避坑提示:UDP 模式下 Agent 默认端口为 6831/6832,如果业务 Pod 与 Agent 不在同一网络命名空间(如非 DaemonSet 部署),需确保 UDP 包可达。生产环境建议使用 gRPC 或 Unix Domain Socket 提升可靠性。

2.2.2 jaeger-collector:无状态接收与处理枢纽

Collector 是 Jaeger 架构中的核心处理层,负责接收来自 Agent 或 SDK 直连的 Span 数据,执行以下操作:

  1. 数据校验:检查 Span 的 TraceID、SpanID、时间戳等必填字段是否合法。
  2. 采样决策:根据配置的采样策略(概率采样、速率限制、远程采样)决定是否保留该 Trace。
  3. 存储路由:将 Span 写入后端存储(Elasticsearch / Cassandra / Badger),或写入 Kafka 缓冲队列。
  4. 依赖分析:在内存中维护服务间调用关系的临时统计,定期刷新到存储。

Collector 为无状态设计,可通过水平扩展 Pod 副本数来提升吞吐量。典型部署会前置负载均衡器(如 Nginx / Envoy)或使用 Kubernetes Service 的轮询机制。

2.2.3 jaeger-ingester:Kafka 消费与批量写入

当引入 Kafka 作为缓冲层时,Ingester 组件负责从 Kafka Topic 中消费 Span 数据,并批量写入存储后端。其核心价值在于:

  • 削峰填谷:应对业务突发流量,避免存储后端被瞬时写入压垮。
  • 解耦采集与存储:Collector 只负责写入 Kafka,写入速度不受存储性能影响。
  • 重试与容错:Kafka 提供持久化,Ingester 消费失败后可重新消费。
配置项默认值说明
kafka.brokerslocalhost:9092Kafka 集群地址
kafka.topicjaeger-spansSpan 数据写入的 Topic
ingester.flush-interval1s批量写入存储的时间间隔
ingester.flush-bytes4MB触发批量写入的数据量阈值

2.2.4 jaeger-query:检索 API 与可视化 UI

Query 组件对外提供链路检索能力,包含两个核心接口:

  • HTTP API:RESTful 接口,支持按 TraceID、服务名、标签、时间范围等条件查询。
  • gRPC API:用于 Jaeger UI 后端与 Query 服务之间的高效通信。

Query 服务内嵌 Jaeger UI(React 前端),提供 Trace 详情页、服务拓扑图、性能分析等可视化能力。Query 本身也是无状态服务,可水平扩展以应对高并发查询。

2.3 完整数据流详解

一条 Span 从业务代码中产生到最终在 UI 上展示,经历以下完整路径:

Span 数据流时序图 Span 数据流时序图 SDK Agent Collector Kafka Ingester 存储 ① 生成 Span ② 批量压缩 ③ 校验/采样 ④ 缓冲持久 ⑤ 批量写入 ⑥ 索引存储 数据流关键特征 端到端延迟通常 < 2s(无 Kafka)或 < 5s(含 Kafka 缓冲) Agent → Collector 使用 gRPC 时支持流式传输,减少连接开销
生产实践:在 Kubernetes 环境中,Agent 通常以 DaemonSet 方式部署,每个 Node 一个 Pod;Collector 和 Query 以 Deployment 方式部署,通过 HPA 自动扩缩容;Kafka 和存储(ES/Cassandra)建议使用独立集群或托管服务,避免资源争抢。

2.4 组件对比与选型建议

组件状态水平扩展关键依赖推荐部署方式
jaeger-agent有状态(本地缓存)随 Node 自动扩展无DaemonSet / Sidecar
jaeger-collector无状态支持(HPA)存储 / KafkaDeployment + Service
jaeger-ingester有状态(消费偏移)支持(需分区)KafkaDeployment + 固定分区
jaeger-query无状态支持(HPA)存储Deployment + Service
选型建议:日均 Span 量 < 1 亿且对实时性要求极高时,可跳过 Kafka,Collector 直写存储;日均 Span 量 > 5 亿或存在明显流量毛刺时,强烈建议引入 Kafka 缓冲层,避免存储后端被瞬时流量打满。

2.5 本章小结

Jaeger 的组件化设计实现了采集、处理、缓冲、存储、查询的职责分离。Agent 负责本地接入与压缩,Collector 负责无状态处理与路由,Kafka + Ingester 提供弹性缓冲,Query 负责检索与可视化。理解各组件的数据流与部署约束,是后续进行服务画像、配置发布和故障定位的基础。