Micrometer 系列【39】链路追踪:入门案例 | 环境准备
文章目录
- 1. Jaeger
- 1.1 项目简介
- 1.2 v2 版本
- 1.3 与 OpenTelemetry 的关系
- 1.4 Docker 部署
- 1.5 vs Zipkin
- 1.6 vs Apache SkyWalking
- 2. OpenTelemetry
- 2.1 OTLP 协议
- 2.2 OTel 框架
- 2.3 vs Brave
- 2.4 vs Micrometer
- 3. 依赖配置
- 3.1 Micrometer Tracing 门面
- 3.2 追踪器
- 3.3 导出器
1. Jaeger
美/ˈjeɪɡɚ/
1.1 项目简介
官网地址
Jaeger是一套分布式追踪平台,由优步(Uber Technologies)于2016年开源,随后捐赠给云原生计算基金会(CNCF),现已成为毕业级项目。
借助Jaeger,可以实现:
- 监控、排查分布式业务流程
- 定位性能瓶颈
- 追溯故障根因
- 分析服务依赖关系
1.2 v2 版本
发布时间:2024-11-12
Jaeger作为主流开源分布式追踪平台,已经稳定运行9年,深度参与OpenTracing、OpenTelemetry等行业标准化工作,也是CNCF最早一批毕业项目。历经60多个版本迭代,Jaegerv2迎来重大架构升级。
新版本以OpenTelemetry Collector作为底层基座,并在此基础上扩展实现Jaeger独有特性。整体带来大量改进与调整,架构更灵活、扩展性更强,与OpenTelemetry生态深度对齐。完整介绍可阅读官方博文。
核心特性:
- 数据模型源自
OpenTracing规范 - 原生兼容
OpenTelemetry - 内置多种存储后端:
Elasticsearch、OpenSearch、Cassandra、Badger(单机本地文件存储)、Kafka(中间缓冲)、内存存储 - 支持通过远程存储
API对接自定义存储实现,具备良好扩展性 - 服务拓扑 / 依赖关系图谱
- 自适应采样
- 服务性能监控(
SPM) - 采集后数据处理流水线
1.3 与 OpenTelemetry 的关系
两个项目定位不同:
OpenTelemetry目标是提供多语言统一API和SDK,让应用可以向外输出各类遥测数据,对接任意指标、链路后端。Jaeger定位主要是链路追踪后端:接收追踪遥测数据,负责数据处理、聚合、分析与可视化展示。
Jaeger最初基于OpenTracing标准设计,UI界面中仍保留OpenTracing术语,但所有概念均可直接映射到OpenTelemetry追踪数据模型。
| 能力说明 | OpenTracing 概念 | OpenTelemetry 概念 |
|---|---|---|
| 将追踪表达为有向无环图(不限于树形结构) | span references(跨度引用) | span links(跨度链接) |
| 强类型跨度属性 | span tags(标签) | span attributes(属性) |
| 强类型事件 / 日志 | span logs(跨度日志) | span events(跨度事件) |
1.4 Docker 部署
docker-compose.yml直接部署:
version:"3.8"services:# ==================== Jaeger v2 ====================jaeger:image:cr.jaegertracing.io/jaegertracing/jaeger:2.20.0container_name:jaegeruser:rootports:-"16686:16686"# Jaeger Web UI-"4317:4317"# OTLP gRPC receiver-"4318:4318"# OTLP HTTP receiver-"5778:5778"# Config service / sampling strategies-"9411:9411"# Zipkin HTTP endpoint (兼容Zipkin客户端)environment:-COLLECTOR_OTLP_ENABLED=true-SPAN_STORAGE_TYPE=badger-BADGER_EPHEMERAL=false-BADGER_DIRECTORY_VALUE=/badger/data-BADGER_DIRECTORY_KEY=/badger/keyvolumes:-jaeger_data:/badgervolumes:jaeger_data:启动:
docker-composeup-d访问地址:http://127.0.0.1:16686
1.5 vs Zipkin
二者都是链路后端存储&可视化服务;Zipkin轻量老牌;Jaeger v2云原生新标准,CNCF毕业项目。
核心对比表:
| 对比维度 | Zipkin | Jaeger(v2) |
|---|---|---|
| 项目归属 | OpenZipkin 社区 | CNCF 毕业项目 |
| 底层架构 | 极简单体架构,读写不分离 | 模块化架构:Collector / Query / Ingester,可独立扩缩容;All-in-One 模式用于测试 |
| 标准协议 | 原生 Zipkin 协议(JSON/Thrift);不原生支持 OTLP(新版本虽支持但非主流) | 原生优先 OTLP(OpenTelemetry 标准);同时兼容 Zipkin 格式,平滑迁移老系统 |
| 数据模型 | 简洁,面向 Dapper 经典模型 | 兼容 OpenTracing & OpenTelemetry;支持span links、事件、丰富属性 |
| 采样能力 | 仅基础概率采样,无远程动态自适应采样 | 头部采样 + 尾部采样 + 自适应采样,支持远程下发采样策略(端口5778) |
| 拓扑依赖图 | 仅一跳直连依赖图 | 两种拓扑:系统架构图 +深度传递依赖图,支持区分服务/接口粒度 |
| 特有功能 | 追求极简,功能克制 | SPM(服务性能监控)、采集后数据处理流水线、丰富查询过滤 |
| 存储支持 | Cassandra、Elasticsearch、MySQL、内存 | Cassandra、Elasticsearch、OpenSearch、Badger本地存储、Kafka缓冲、自定义存储扩展 |
| UI能力 | 简洁够用,适合小规模;缺少高级分析 | 功能更强,支持超大链路(数万条Span)、时序指标面板 |
| 生态趋势 | 存量主流,新项目逐步边缘化;OpenTelemetry 官方已标记 Zipkin Exporter 为废弃 | 云原生事实首选,深度绑定 OpenTelemetry |
1.6 vs Apache SkyWalking
本质差异:
Jaeger v2:专注分布式链路追踪后端,遵循OpenTelemetry云原生标准;SkyWalking:Apache顶级一体化APM平台,原生支持Trace/Metrics/Logs三合一。
核心对比表:
| 对比维度 | Jaeger(v2) | Apache SkyWalking |
|---|---|---|
| 项目归属 | CNCF 毕业项目(Uber开源) | Apache 顶级开源项目,国内生态成熟 |
| 设计定位 | 专业链路追踪系统,重心聚焦Trace查询、分析;指标、日志需要外部组件补齐 | 一站式完整APM平台,链路、时序指标、日志、性能剖析、告警全部内置 |
| 底层架构 | Collector / Query / Storage 模块化;All-in-One 用于测试;基于 OpenTelemetry Collector | OAP 后端 + Agent + UI;轻Agent、重后端,聚合、计算、告警下沉到OAP |
| 数据协议 | 原生优先 OTLP;兼容旧 Jaeger Thrift、Zipkin;主推 OpenTelemetry SDK | 原生 SW 自定义协议;兼容 OTLP/Zipkin v2;支持 OpenTelemetry 接入,但非原生首选 |
| 埋点方式 | 依赖 OpenTelemetry SDK,无内置字节码Agent;代码无侵入 | 内置强大 Java Agent(字节码增强),零代码埋点;同时支持OpenTelemetry手动埋点 |
| 数据模型 | 完全遵循 OpenTelemetry 规范,span links、事件、属性完善 | 自有Segment模型,兼容OTel数据模型;上下文传递默认sw8协议头 |
| 采样策略 | 头部采样、尾部采样、自适应采样;支持远程动态采样配置(5778端口) | 固定比例采样、速率限制、慢请求/异常条件采样;双层采样(Agent+OAP) |
| 拓扑依赖图 | 自动推导服务依赖;基础架构拓扑 + 深度链路依赖图 | 拓扑能力更强;区分服务/实例/接口粒度;支持数据库、消息中间件完整依赖展示 |
| 指标能力 | 内置SPM生成RED指标;无法独立替代Prometheus,指标体系薄弱 | 原生内置完整服务指标(RED、JVM、中间件),开箱即用,不依赖外部监控组件 |
| 告警体系 | 无原生告警;告警规则依赖 Prometheus + Alertmanager | 内置告警引擎,支持多维度告警规则,原生对接Webhook,无需额外组件 |
| 日志联动 | 仅标准兼容,需要 Loki 等外部系统打通TraceID | 原生日志-Trace关联;Agent自动携带Trace上下文,一站式检索 |
| 性能剖析 | 无内置Profiling | 支持Java代码剖析、eBPF无侵入剖析 |
| 存储支持 | Badger、Elasticsearch、Cassandra、Kafka缓冲 | Elasticsearch、BanyanDB、MySQL、TiDB |
| UI能力 | 链路查询、Trace对比、瀑布图、SPM面板;UI专注链路排障 | 完整大盘、服务监控、拓扑、链路、日志、告警统一控制台,开箱即用 |
| 生态趋势 | 云原生、OpenTelemetry标准路线首选,多语言混合栈、Service Mesh友好 | 国内微服务(Java为主)大规模落地极广;适合希望一套组件搞定监控的团队 |
| 运维成本 | 单纯链路组件;完整可观测体系需要搭配 Prometheus + Loki + Grafana | 单体一体化;起步运维简单;大规模集群OAP需要横向扩容调优 |
2. OpenTelemetry
官网主页
GitHub 组织主地址
2.1 OTLP 协议
OpenTelemetry官方定义的遥测数据传输协议,是云原生可观测领域事实标准。
作用:应用程序把Traces(链路)、Metrics(指标)、Logs(日志)三类遥测数据,通过统一协议发送到采集后端。
支持两种通信模式:
OTLP/gRPC:默认端口4317二进制传输,性能更高,生产首选;OTLP/HTTP:默认端口4318 Protobuf编码通过HTTP承载,防火墙友好,部分环境备选。
核心优势:
统一标准:一套协议承载
Trace/Metric/Log三类遥测;不再每种数据单独一套协议。跨语言通用:
Java/Go/Python/JS/Rust所有OpenTelemetry SDK统一输出OTLP。生态广泛兼容:
OTel Collector、Jaegerv2、Tempo、SigNoz、Loki、各类商业APM原生支持OTLP。可扩展:支持携带
Baggage、Exemplars(指标样例,Metrics关联Trace),完全对齐W3C追踪规范。
2.2 OTel 框架
OpenTelemetry(OTel)是CNCF毕业级开源项目,一套厂商无关、标准化的可观测埋点框架。一次埋点,可以把数据发送到任意后端:Jaeger、Tempo、Prometheus、Loki、SkyWalking、商用APM等。
核心组成:
多语言
SDK(Java/Go/Python/JS等):提供统一API,用来手动埋点、自动采集(HTTP、RPC、数据库、MQ)。输出标准格式:OTLP。OpenTelemetry Collector(OTel Collector):独立中间代理进程。接收应用上报的遥测数据 → 处理(过滤、采样、转换协议)→ 转发到存储后端。支持同时接收OTLP、Zipkin、Jaeger格式数据,起到过渡和解耦作用。
发展历史:
2.3 vs Brave
Brave(OpenZipkin)是Java链路客户端SDK,负责创建Span、管理生命周期、B3追踪上下文传播,输出格式Zipkin协议(Thrift/JSON)。
Brave没有被淘汰,但属于「存量稳健方案,不再是新项目首选」,生态天花板明显,长期趋势边缘化。
2.4 vs Micrometer
Micrometer是Java 生态专属的遥测门面层;OpenTelemetry是跨语言、覆盖三类遥测信号的完整标准规范 与 SDK 体系。
Micrometer最初聚焦指标(Metrics),拥有独立指标模型,作为统一门面,可以向Prometheus、InfluxDB、Graphite、OTLP等多种监控后端输出指标数据。
链路追踪:micrometer-tracing提供追踪统一抽象API,内置NOOP空实现,本身不具备完整追踪能力,可以二选一桥接底层实现:
Brave(Zipkin生态)OpenTelemetry Java SDK(依赖micrometer-tracing-bridge-otel,最终输出标准OTLP追踪数据)
日志:Micrometer项目没有定义日志仪器化 API ,不负责应用日志采集。业务日志一般依托Logback/Log4j2,结合OpenTelemetry日志桥接或OTel Collector完成采集。
| 对比维度 | Micrometer | OpenTelemetry |
|---|---|---|
| 定位 | Java生态专属遥测门面(Facade) | 跨语言完整遥测标准规范 + SDK实现 |
| 支持语言 | 仅Java/JVM | Java、Go、Python、JS、.NET、Rust等全主流语言 |
| 遥测信号覆盖 | Metrics + Tracing ❌无日志仪器化API | Traces / Metrics / Logs 三位一体完整标准 |
| 指标模型 | 自有独立指标模型 输出OTLP时需要模型转换 | 原生OTel Metric规范,OTLP原生语义 |
| 指标能力依赖OTel? | ❌ 完全独立otlp-registry只是协议导出器 | 原生内置Metrics SDK |
| 链路追踪实现 | micrometer-tracing提供抽象API底层二选一:Brave / OpenTelemetry(桥接模式) | SDK原生实现Span、上下文传播 |
| 日志处理 | 不负责日志采集、日志埋点API | 提供日志仪器规范、日志桥接方案 |
| 典型使用场景 | Spring Boot 默认监控,兼容Prometheus等传统监控 | 云原生跨服务、多语言系统,统一OTLP采集链路 |
| 业务代码耦合 | 面向 Micrometer API,切换底层实现无需改业务代码 | 面向 OpenTelemetry 官方API |
3. 依赖配置
完整POM示例:
<dependencyManagement><dependencies><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-bom</artifactId><version>1.17.0</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bom</artifactId><version>1.7.0</version><type>pom</type><scope>import</scope></dependency><!-- 引入 OTel Instrumentation BOM 避免版本冲突 --><dependency><groupId>io.opentelemetry.instrumentation</groupId><artifactId>opentelemetry-instrumentation-bom</artifactId><version>2.30.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-core</artifactId></dependency><!-- Micrometer Tracing 抽象 --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId></dependency><!-- OTel桥接,用于生成 Span --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-otel</artifactId></dependency><!-- OTel OTLP Exporter:Tracing 通过 OTLP 协议导出到 Jeager--><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-exporter-otlp</artifactId></dependency></dependencies>3.1 Micrometer Tracing 门面
Micrometer Tracing提供物料清单(BOM)统一管理所有子模块版本。
Maven依赖示例:
<dependencyManagement><dependencies><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bom</artifactId><version>${micrometer-tracing.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId></dependency></dependencies>3.2 追踪器
核心模块 (micrometer-tracing)只定义接口,不引入任何具体追踪库,需要引入对应的追踪桥接实现模块:
micrometer-tracing-bridge-bravemicrometer-tracing-bridge-otel
核心模块micrometer-tracing的追踪器Tracer只提供了NOOP的空壳:
// 来自 Tracer.java — 核心模块只定义接口 + NOOP 实现TracerNOOP=newTracer(){@OverridepublicSpannextSpan(){returnSpan.NOOP;// 返回空 Span,不做任何事}// ...};如果没有桥接实现,你拿到的永远是这个NOOP,所有Span都不会被记录,所有追踪数据都石沉大海。这就像你有了SLF4J的Logger接口,但没有Logback或Log4j2的实现一样。
桥接实现做了真正的委托工作:
// 来自 BraveTracer.java — 桥接实现真正干活publicclassBraveTracerimplementsTracer{privatefinalbrave.Tracertracer;// ← 真实的 Brave Tracer@OverridepublicSpannextSpan(){returnnewBraveSpan(this.tracer.nextSpan());// ← 委托给 Brave}}Micrometer Tracing支持以下追踪实现:
OpenZipkin BraveOpenTelemetry
下述Maven依赖示例(前提:已引入Micrometer Tracing BOM)
Brave追踪器:
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId></dependency>OpenTelemetry追踪器(本次引入):
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-otel</artifactId></dependency>⚠️ 注意:类路径中只能选择一种桥接实现,不要同时引入两个桥接包。
3.3 导出器
桥接实现解决了怎么创建Span,链路再往前一步,但Span创建出来后往哪发?这就轮到导出器/上报器了。
Micrometer Tracing不重复造轮子,真正的导出能力来自Brave和OpenTelemetry的原生生态。
Wavefront上报器已标记废弃:Wavefront官方已发布生命周期终止公告。
Brave自带对Zipkin的一等支持,支持多种传输方式:
| 导出方式 | Brave 依赖 |
|---|---|
| Zipkin (HTTP) | io.zipkin.reporter2:zipkin-sender-urlconnection |
| Zipkin (Kafka) | io.zipkin.reporter2:zipkin-sender-kafka |
| Zipkin (RabbitMQ) | io.zipkin.reporter2:zipkin-sender-amqp-client |
| Zipkin (ActiveMQ) | io.zipkin.reporter2:zipkin-sender-activemq |
OpenTelemetry的生态更加丰富:
| 导出方式 | OTel 依赖 |
|---|---|
| OTLP (gRPC/HTTP) | io.opentelemetry:opentelemetry-exporter-otlp |
| Zipkin | io.opentelemetry:opentelemetry-exporter-zipkin |
| Jaeger (gRPC/Thrift) | io.opentelemetry:opentelemetry-exporter-jaeger |
| Logging | io.opentelemetry:opentelemetry-exporter-logging |
| Prometheus | 通过OTel Collector间接支持 |
这里使用的opentelemetry-exporter-otlp是OpenTelemetry官方提供的标准化导出器,通过OTLP协议(gRPC或HTTP)将Span数据发送到任意兼容的后端(如Jaeger、Grafana Tempo、OTel Collector、Datadog等)。
通过OpenTelemetryBOM来统一管理版本:
<!-- 引入 OTel Instrumentation BOM 避免版本冲突 --><dependency><groupId>io.opentelemetry.instrumentation</groupId><artifactId>opentelemetry-instrumentation-bom</artifactId><version>2.30.0</version><type>pom</type><scope>import</scope></dependency>引入opentelemetry-exporter-otlp:
<!-- OTel OTLP Exporter:Tracing 通过 OTLP 导出--><dependency><groupId>io.opentelemetry</groupId><artifactId>opentelemetry-exporter-otlp</artifactId></dependency>