2. Jaeger 整体架构:Agent、Collector、Query、UI 组件及其数据流关系
Jaeger 作为 CNCF 毕业的分布式追踪系统,其架构设计遵循“轻量采集、异步处理、模块化存储”的原则。理解 Jaeger 的四大核心组件——Agent、Collector、Query、UI——以及它们之间的数据流关系,是掌握 Jaeger 模块化设计的基础,也是后续进行配置环境一致性验证的前提。
2.1 核心组件概述
下表从职责、部署位置、关键特性三个维度,对 Jaeger 的四大组件进行对比,帮助快速建立整体认知。
| 组件 | 核心职责 | 典型部署位置 | 关键特性 |
|---|---|---|---|
| Agent | 接收应用发出的 Span 数据,批量转发给 Collector | 与应用程序同主机部署(Sidecar 或 DaemonSet) | 轻量级、无状态、支持 UDP/gRPC 接收 |
| Collector | 接收 Agent 或应用直连的 Span,校验、采样、存储 | 独立集群部署(无状态水平扩展) | 支持多种存储后端(Cassandra/Elasticsearch/Badger) |
| Query | 提供 API 接口,从存储中检索 Trace 和 Span | 独立服务(通常与 UI 同集群部署) | 支持 TraceID 查询、服务/操作过滤、依赖分析 |
| UI | 可视化展示 Trace 详情、服务拓扑、性能指标 | Web 前端(通常与 Query 服务绑定) | 基于 React,通过 Query API 获取数据 |
架构要点:Agent 是“最后一公里”的采集代理,Collector 是“数据中枢”,Query 是“数据出口”,UI 是“用户界面”。四者职责清晰,通过标准协议解耦,这是 Jaeger 模块化设计的核心体现。
2.2 组件间数据流关系
数据从应用程序产生到最终在 UI 上呈现,经历了一条清晰的管道。下图展示了 Jaeger 的完整数据流架构,包含两种常见的采集路径:带 Agent 的标准路径和应用直连 Collector 的简化路径。
2.3 组件间通信协议
Jaeger 组件之间的通信采用标准化的协议,确保模块间的松耦合。下表总结了各组件间的通信方式与协议细节。
| 通信路径 | 协议 | 端口(默认) | 数据格式 | 说明 |
|---|---|---|---|---|
| App → Agent | UDP / gRPC | 6831 (UDP) / 6832 (UDP) / 14250 (gRPC) | Thrift / Protobuf | UDP 为传统方式,gRPC 为推荐方式 |
| App → Collector | gRPC | 14250 | Protobuf | 直连路径,适用于 Agent 不可用场景 |
| Agent → Collector | gRPC | 14250 | Protobuf | 批量发送,支持压缩和重试 |
| Collector → Storage | gRPC / HTTP | 取决于存储后端 | Span 模型 | 通过存储插件接口解耦 |
| Query → Storage | gRPC / HTTP | 取决于存储后端 | Span 模型 | 只读操作,支持缓存 |
| UI → Query | HTTP (REST / gRPC-Web) | 16686 (UI) / 16685 (gRPC) | JSON / Protobuf | 前端通过 Query API 获取数据 |
配置一致性验证要点:在验证环境一致性时,需要重点检查 Agent 与 Collector 之间的 gRPC 端点配置(
--collector.host-port)、Collector 的存储后端连接串(--cassandra.keyspace 或 --es.server-urls)、以及 Query 服务暴露的端口是否与 UI 配置匹配。任何一端的不一致都会导致数据链路中断。
2.4 数据流中的关键行为
理解数据在组件间的流转细节,有助于在配置验证中快速定位问题。以下是数据流中的三个关键行为:
- Span 的批量发送:Agent 不会逐条转发 Span,而是将多个 Span 打包成一个批次(Batch),通过 gRPC 流式发送给 Collector。批次大小和发送间隔可通过
--jaeger.agent.batch-size和--jaeger.agent.batch-interval配置。 - Collector 的采样决策:Collector 在接收 Span 后,会根据采样策略(概率采样、速率限制采样、远程采样)决定是否保留该 Trace。采样配置(如
--sampling.strategies-file)是环境一致性验证的高频检查项。 - Query 的 Trace 组装:Query 服务从存储中检索属于同一个 TraceID 的所有 Span,按照时间戳和父子关系组装成完整的 Trace 树,再通过 API 返回给 UI。如果存储后端索引不一致,可能导致 Trace 不完整。
2.5 模块化设计的优势
Jaeger 的组件化架构为配置环境一致性验证带来了以下优势:
- 独立验证:每个组件可以单独进行配置校验,例如单独验证 Agent 的端口监听状态、Collector 的存储连接健康度、Query 的 API 响应。
- 配置隔离:Agent、Collector、Query 的配置文件相互独立,修改一个组件的配置不会影响其他组件,降低了配置冲突的风险。
- 版本兼容:组件间通过 Protobuf 协议通信,只要协议版本兼容,不同版本的组件可以混合部署,便于渐进式升级和配置迁移。
- 可观测性:每个组件都暴露了自身的指标(Metrics)和日志(Logs),可以通过 Prometheus 和 ELK 等工具监控组件的健康状态,辅助配置验证。
常见配置陷阱:在微服务架构中,如果 Agent 与应用程序之间的 UDP 端口(6831/6832)被防火墙或容器网络策略阻断,Span 数据将丢失且无显式报错。验证时务必确认网络连通性,推荐使用 gRPC 协议(端口 14250)以获得更可靠的传输保障。
2.6 数据流中的配置一致性关键点
在分布式环境中,配置一致性验证的核心是确保数据流路径上的每个节点都能正确识别并连接到下一个节点。以下是基于数据流关系的配置一致性关键检查点:
- Agent 端:检查
--reporter.grpc.host-port是否指向正确的 Collector 地址(多个地址用逗号分隔)。如果 Agent 无法连接 Collector,Span 数据会积压在 Agent 内存中,达到上限后丢弃。 - Collector 端:检查
--cassandra.servers或--es.server-urls是否与存储后端的实际地址一致。Collector 启动时会进行存储连接测试,失败则无法提供服务。 - Query 端:检查
--query.storage-type和对应的存储连接参数是否与 Collector 使用的存储后端一致。如果 Query 连接了不同的存储实例,将无法查询到 Collector 写入的数据。 - UI 端:检查 UI 的
JAEGER_QUERY_ENDPOINT环境变量是否指向正确的 Query 服务地址。如果地址错误,UI 将无法加载 Trace 数据。
验证技巧:在非生产环境中,可以使用 Jaeger 自带的
jaeger-query 的 /api/services 端点来快速验证数据流是否通畅。如果该端点返回了预期的服务列表,说明从应用 → Agent → Collector → Storage → Query 的整条链路配置正确。