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 图展示了标准部署模式下的数据流转路径。
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)
2.4.2 高可用模式(引入 Kafka + 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 是必选项,而非可选项。