Micrometer 系列【39】链路追踪:入门案例 | 环境准备

文章目录

  • [1. Jaeger](#1. Jaeger)
    • [1.1 项目简介](#1.1 项目简介)
    • [1.2 v2 版本](#1.2 v2 版本)
    • [1.3 与 OpenTelemetry 的关系](#1.3 与 OpenTelemetry 的关系)
    • [1.4 Docker 部署](#1.4 Docker 部署)
    • [1.5 vs Zipkin](#1.5 vs Zipkin)
    • [1.6 vs Apache SkyWalking](#1.6 vs Apache SkyWalking)
  • [2. OpenTelemetry](#2. OpenTelemetry)
    • [2.1 OTLP 协议](#2.1 OTLP 协议)
    • [2.2 OTel 框架](#2.2 OTel 框架)
    • [2.3 vs Brave](#2.3 vs Brave)
    • [2.4 vs Micrometer](#2.4 vs Micrometer)
  • [3. 依赖配置](#3. 依赖配置)
    • [3.1 Micrometer Tracing 门面](#3.1 Micrometer Tracing 门面)
    • [3.2 追踪器](#3.2 追踪器)
    • [3.3 导出器](#3.3 导出器)

1. Jaeger

/ˈjeɪɡɚ/

1.1 项目简介

官网地址

Jaeger 是一套分布式追踪平台,由优步(Uber Technologies)于 2016 年开源,随后捐赠给云原生计算基金会(CNCF),现已成为毕业级项目。

借助 Jaeger,可以实现:

  • 监控、排查分布式业务流程
  • 定位性能瓶颈
  • 追溯故障根因
  • 分析服务依赖关系

1.2 v2 版本

发布时间:2024-11-12

Jaeger 作为主流开源分布式追踪平台,已经稳定运行 9 年,深度参与 OpenTracingOpenTelemetry 等行业标准化工作,也是 CNCF 最早一批毕业项目。历经 60 多个版本迭代,Jaeger v2 迎来重大架构升级。

新版本以 OpenTelemetry Collector 作为底层基座,并在此基础上扩展实现 Jaeger 独有特性。整体带来大量改进与调整,架构更灵活、扩展性更强,与 OpenTelemetry 生态深度对齐。完整介绍可阅读官方博文。

核心特性:

  • 数据模型源自 OpenTracing 规范
  • 原生兼容 OpenTelemetry
  • 内置多种存储后端:ElasticsearchOpenSearchCassandraBadger(单机本地文件存储)、Kafka(中间缓冲)、内存存储
  • 支持通过远程存储 API 对接自定义存储实现,具备良好扩展性
  • 服务拓扑 / 依赖关系图谱
  • 自适应采样
  • 服务性能监控(SPM
  • 采集后数据处理流水线

1.3 与 OpenTelemetry 的关系

两个项目定位不同:

  • OpenTelemetry 目标是提供多语言统一 APISDK,让应用可以向外输出各类遥测数据,对接任意指标、链路后端。
  • 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 直接部署:

yml 复制代码
version: "3.8"
services:
  # ==================== Jaeger v2 ====================
  jaeger:
    image: cr.jaegertracing.io/jaegertracing/jaeger:2.20.0
    container_name: jaeger
    user: root
    ports:
      - "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/key
    volumes:
      - jaeger_data:/badger
volumes:
  jaeger_data:

启动:

bash 复制代码
docker-compose up -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 云原生标准;
  • SkyWalkingApache 顶级一体化 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 CollectorJaeger v2、TempoSigNozLoki、各类商业 APM 原生支持 OTLP

  • 可扩展 :支持携带 BaggageExemplars(指标样例,Metrics 关联 Trace),完全对齐 W3C 追踪规范。

2.2 OTel 框架

OpenTelemetryOTel)是 CNCF 毕业级开源项目,一套厂商无关、标准化的可观测埋点框架。一次埋点,可以把数据发送到任意后端:JaegerTempoPrometheusLokiSkyWalking、商用 APM 等。

核心组成:

  • 多语言 SDKJava / Go / Python / JS 等):提供统一 API,用来手动埋点、自动采集(HTTPRPC、数据库、MQ)。输出标准格式:OTLP

  • OpenTelemetry CollectorOTel Collector):独立中间代理进程。接收应用上报的遥测数据 → 处理(过滤、采样、转换协议)→ 转发到存储后端。支持同时接收 OTLPZipkinJaeger 格式数据,起到过渡和解耦作用。

发展历史:

2.3 vs Brave

BraveOpenZipkin)是 Java 链路客户端 SDK ,负责创建 Span、管理生命周期、B3 追踪上下文传播,输出格式 Zipkin 协议(Thrift / JSON)。

Brave 没有被淘汰,但属于「存量稳健方案,不再是新项目首选」,生态天花板明显,长期趋势边缘化。

2.4 vs Micrometer

MicrometerJava 生态专属的遥测门面层OpenTelemetry跨语言、覆盖三类遥测信号的完整标准规范 与 SDK 体系

Micrometer 最初聚焦指标(Metrics),拥有独立指标模型,作为统一门面,可以向 PrometheusInfluxDBGraphiteOTLP 等多种监控后端输出指标数据。

链路追踪micrometer-tracing 提供追踪统一抽象 API ,内置 NOOP 空实现,本身不具备完整追踪能力,可以二选一桥接底层实现:

  • BraveZipkin生态)
  • 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 示例:

xml 复制代码
    <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 依赖示例:

xml 复制代码
<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-brave
  • micrometer-tracing-bridge-otel

核心模块 micrometer-tracing 的追踪器 Tracer 只提供了 NOOP 的空壳:

java 复制代码
// 来自 Tracer.java --- 核心模块只定义接口 + NOOP 实现
Tracer NOOP = new Tracer() {
    @Override
    public Span nextSpan() {
        return Span.NOOP;   // 返回空 Span,不做任何事
    }
    // ...
};

如果没有桥接实现,你拿到的永远是这个 NOOP ,所有 Span 都不会被记录,所有追踪数据都石沉大海。这就像你有了 SLF4JLogger 接口,但没有 LogbackLog4j2 的实现一样。

桥接实现做了真正的委托工作:

java 复制代码
// 来自 BraveTracer.java --- 桥接实现真正干活
public class BraveTracer implements Tracer {
    private final brave.Tracer tracer;  // ← 真实的 Brave Tracer

    @Override
    public Span nextSpan() {
        return new BraveSpan(this.tracer.nextSpan());  // ← 委托给 Brave
    }
}

Micrometer Tracing 支持以下追踪实现:

  • OpenZipkin Brave
  • OpenTelemetry

下述 Maven 依赖示例(前提:已引入 Micrometer Tracing BOM

Brave 追踪器:

xml 复制代码
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>

OpenTelemetry 追踪器(本次引入):

xml 复制代码
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>

⚠️ 注意:类路径中只能选择一种桥接实现,不要同时引入两个桥接包

3.3 导出器

桥接实现解决了怎么创建 Span ,链路再往前一步,但 Span 创建出来后往哪发?这就轮到导出器/上报器了。

Micrometer Tracing 不重复造轮子,真正的导出能力来自 BraveOpenTelemetry 的原生生态。

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-otlpOpenTelemetry 官方提供的标准化导出器,通过 OTLP 协议(gRPCHTTP)将 Span 数据发送到任意兼容的后端(如 JaegerGrafana TempoOTel CollectorDatadog 等)。

通过 OpenTelemetryBOM 来统一管理版本:

xml 复制代码
            <!-- 引入 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

xml 复制代码
        <!-- OTel OTLP Exporter:Tracing 通过 OTLP 导出-->
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp</artifactId>
        </dependency>

相关推荐
chuan.bai1 小时前
Java RAG 实战(第 3 篇):从交互式聊天到多轮上下文
java·人工智能·macos·ai
952361 小时前
Sentinel
java·后端·spring·sentinel·springcloud
阿pin1 小时前
Java随笔-JDK7 HashMap头插法为何能导致死循环?
java·开发语言·hashmap
李可以量化2 小时前
Tornado 从了解到精通(一)下:异步与非阻塞 IO 核心原理
java·数据库·tornado
yurenpai(27届找实习中)2 小时前
从销售订单推送 MES 看懂微服务调用(二):DTO 转换与 OpenFeign 调用
java·微服务·架构·服务调用
Patrick在香港2 小时前
Python爬虫框架实战:优雅抓取香港政府公开API数据的通用方案
java·开发语言·爬虫·python·ai编程·数据可视化·可用性测试
hey_sml2 小时前
MySQL常用操作速记:从字符集到游标全解析
java·开发语言·mysql
掉鱼的猫2 小时前
Solon AOT & Native:三段式编译,从 Java 到原生可执行文件
java·云原生
Java内核笔记2 小时前
容错能力进入 spring-core:Spring Boot 4 原生重试机制全解析
java·后端