2. Jaeger 基础回顾:Jaeger 架构组件及数据流

在深入值班台高可用部署之前,必须重新夯实 Jaeger 的核心架构。Jaeger 遵循 “端侧采集 → 代理转发 → 后端处理 → 存储查询” 的经典链路。整个系统由四个核心组件构成:Agent、Collector、Query 和 Ingester。理解每个组件的职责以及 Span 数据在它们之间的流转路径,是后续设计高可用拓扑的基础。

2.1 核心组件职责速览

组件 核心职责 部署形态 关键端口
Agent 本地 Sidecar 或 DaemonSet,接收应用发出的 UDP 数据,批量压缩后转发给 Collector 与业务应用同节点部署 6831/6832 (UDP), 5778 (HTTP)
Collector 接收 Agent 或应用直推的 Span,校验、采样、构建 Trace,写入存储后端 无状态服务,可水平扩展 14267 (gRPC), 14268 (HTTP)
Query 提供 API 和 UI 界面,从存储中检索 Trace 并返回给前端展示 无状态服务,可水平扩展 16686 (HTTP/UI), 16687 (gRPC)
Ingester 从 Kafka 消费 Span 数据,批量写入存储后端,解耦 Collector 与存储 有状态服务(依赖 Kafka 消费组) 14270 (gRPC), 14269 (HTTP)
架构演进提示: 早期 Jaeger 版本中 Ingester 并非必选组件。在值班台高可用场景下,引入 Kafka + Ingester 是防止 Collector 抖动导致数据丢失的关键手段。

2.2 数据流全景:从 Span 产生到持久化

一条完整的 Trace 数据流通常经历以下五个阶段。下面的 SVG 图展示了标准部署模式下的数据流转路径。

Jaeger 标准数据流架构图 Jaeger 标准数据流:Span 产生 → 存储 → 查询 Application Agent Collector Kafka Ingester Storage Query UDP (Thrift) gRPC 异步写入 消费 批量写入 读取 说明:Agent 与 App 同节点部署;Collector 无状态;Kafka 作为削峰缓冲层;Ingester 负责最终写入。

2.3 组件间通信协议与端口矩阵

在生产环境中,端口规划直接影响网络安全策略和 Service Mesh 配置。下表列出了各组件间通信的默认协议与端口。

源组件 目标组件 协议 默认端口 用途说明
Application Agent UDP (Thrift) 6831 / 6832 应用通过 Jaeger Client 发送 Span
Application Collector HTTP / gRPC 14268 / 14267 跳过 Agent 直接推送(不推荐生产)
Agent Collector gRPC 14267 Agent 批量转发 Span
Collector Kafka TCP (Kafka协议) 9092 异步写入 Kafka Topic
Ingester Kafka TCP (Kafka协议) 9092 从 Kafka 消费 Span
Ingester Storage gRPC / HTTP 14270 / 14269 批量写入 Elasticsearch/Cassandra
Query Storage gRPC / HTTP 14270 / 14269 读取 Trace 数据
Browser Query HTTP 16686 Jaeger UI 访问

2.4 关键数据流路径:标准模式 vs 高可用模式

在值班台场景下,我们更关注数据流的可靠性。下面通过两个独立图示对比标准模式与高可用模式的核心差异。

2.4.1 标准模式(无 Kafka)

标准模式数据流 标准模式:App → Agent → Collector → Storage App Agent Collector Storage 风险:Collector 故障或存储抖动时,Span 直接丢失,无缓冲保护。

2.4.2 高可用模式(引入 Kafka + Ingester)

高可用模式数据流 高可用模式:App → Agent → Collector → Kafka → Ingester → Storage App Agent Collector Kafka Ingester Storage 优势:Kafka 作为持久化缓冲,Collector 或 Storage 故障时数据不丢失,Ingester 可重试消费。 注意:Ingester 为有状态组件,需关注消费组偏移量管理和分区再均衡。

2.5 组件部署要点与避坑指南

  • Agent 部署: 推荐使用 DaemonSet 模式,每个 Kubernetes 节点一个 Agent Pod。避免使用 Sidecar 模式,否则会大幅增加资源开销和运维复杂度。
  • Collector 无状态化: 不要将任何本地缓存或状态绑定到 Collector 实例。所有 Collector 实例共享同一个 Kafka 或存储后端,才能实现真正的水平扩缩。
  • Ingester 消费组设计: 每个 Ingester 实例属于同一个 Kafka 消费组。分区数应大于等于 Ingester 副本数,避免出现空闲消费者。
  • Query 只读: Query 服务不参与数据写入,因此可以独立扩缩,不受写入流量影响。在值班台场景下,Query 通常需要配置读超时和连接池,防止大 Trace 查询拖垮 UI。
常见陷阱: 很多团队在初期部署时省略了 Kafka 和 Ingester,直接让 Collector 写入存储。一旦 Collector 或存储出现毛刺,Span 数据就会在 Collector 内存中堆积并触发 OOM,导致数据永久丢失。值班台场景下,Kafka + Ingester 是必选项,而非可选项。

2.6 本章小结