1324 字
约 4 分钟
9
S16-J02 · 接入实战:Spring Boot 3 + Micrometer Tracing + Zipkin

适用读者:要在现有 Spring Boot 3 项目里把链路跑起来的人;照着旧文加 Sleuth 却启动失败的人。
前置:S16-J01、S07(Spring)、S15(Docker)。
覆盖旧文:A-560 → 67 点(§2 Spring Boot 接入、现代接入、采样率、traceId 入日志、请求传播)。
扩展点:E-S16-006(采样率三策略)。
上一篇:S16-J01 · 链路追踪基础:Trace / Span / Parent Span
下一篇:S16-J03 · SkyWalking。


1. 一句话结论

Boot 3 的追踪栈是"Micrometer Tracing(门面)+ Brave/OTel(实现)+ Zipkin(后端)"三件套;缺任何一件,traceId 都不会出现。 而"没出现"最常见的三个原因是:桥接依赖缺失、采样率过低、日志格式没加占位符。


2. 依赖(Spring Boot 3.3.6 / Java 17,2026-11 实测)

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- 门面 + Brave 桥接:生成/传播 traceId 的核心 -->
<dependency>
  <groupId>io.micrometer</groupId>
  <artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<!-- 把 span 上报到 Zipkin -->
<dependency>
  <groupId>io.zipkin.reporter2</groupId>
  <artifactId>zipkin-reporter-brave</artifactId>
</dependency>
依赖 作用 缺了会怎样
micrometer-tracing-bridge-brave 桥接具体实现 无 traceId,日志里是空
zipkin-reporter-brave HTTP 上报 本地有 traceId,Zipkin UI 查不到
spring-boot-starter-actuator 暴露 /actuator 观测端点 Observation 不自动装配

Sleuth 已不适用于 Boot 3:spring-cloud-starter-sleuth 在 Boot 3 中不再被支持,旧文里的写法会直接失败。正确路径就是上面的 Micrometer Tracing。


3. 配置

# application.yml
spring:
  application:
    name: order-service
management:
  tracing:
    sampling:
      probability: 0.10        # 10% 采样;开发环境可设 1.0
  zipkin:
    tracing:
      endpoint: http://localhost:9411/api/v2/spans
logging:
  pattern:
    level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
# 起 Zipkin(内存存储,仅用于本地)
docker run -d --name zipkin -p 9411:9411 openzipkin/zipkin:3.4

预期结果:

2026-11-06 15:02:11.882  INFO [order-service,4bf92f3577b34da6,00f067aa0ba902b7] 1 --- [nio-8080-exec-1] c.e.OrderController : 创建订单 sku=1 qty=2

三个关键点:traceId 非空、spanId 非空、两个服务打印的 traceId 相同。


4. 采样率三策略(E-S16-006)

management.tracing.sampling.probability 是头部采样(在请求入口就决定采不采),简单但会漏掉"低概率但高价值"的请求。

策略 实现 优点 缺点
头部采样 probability: 0.1 零成本、实现简单 错误请求大概率被丢
尾部采样 收集后在 Collector 侧按规则过滤(OTel Collector / Zipkin 侧不做) 错误链路 100% 保留 需要 Collector、内存缓冲
按错误强制采 应用侧对 status=ERROR 打 sampled=1 标记 关键链路必留 需改代码/自定义 sampler

工程折中(推荐起步):

生产 1–5% 头部采样 + 错误链路强制采样 + 慢请求(> P99)强制采样
开发/预发 100%

判据:抽 10 条线上错误告警,能否在 Zipkin 里找到对应 trace?找不到 → 采样策略不合格。


5. traceId 进日志与跨线程传播

5.1 日志

上面 logging.pattern.level 里的 %X{traceId:-} 依赖 MDC。Boot 3 由 Micrometer Tracing 自动注入,前提是走 Spring 的 Observation/拦截器。

场景 traceId 是否自动带 补救
Controller(HTTP 入口) ✅ —
@Async / 线程池 ❌ TaskDecorator 复制 MDC
MQ 消费 ❌ 手动从消息头取 traceparent 并 Span.current() 关联
定时任务 ❌ 新建 root span
// 线程池透传 MDC 的最小实现
@Bean
TaskDecorator mdcDecorator() {
    return runnable -> {
        Map<String, String> ctx = MDC.getCopyOfContextMap();
        return () -> {
            if (ctx != null) MDC.setContextMap(ctx);
            try { runnable.run(); } finally { MDC.clear(); }
        };
    };
}

5.2 跨服务传播

Brave/OTel 会自动注入 traceparent/X-B3-TraceId。自研 HTTP 客户端必须手动传播,否则链路在调用处断掉:

// 用 RestClient 时:Micrometer 的 Observation 会自动包裹;用裸 HttpClient 则要手动
String tp = tracer.currentSpan() != null
    ? "00-" + tracer.currentSpan().context().traceId() + "-" + tracer.currentSpan().context().spanId() + "-01"
    : null;
if (tp != null) request.header("traceparent", tp);

6. 三个"跑不起来"的排查顺序

现象 先查 再看
日志里 traceId 为空 桥接依赖是否存在 logging.pattern.level 是否含 %X{traceId}
Zipkin UI 空白 management.zipkin.tracing.endpoint 是否可达 采样率是否 0;容器网络是否通
两个服务 traceId 不同 调用是否走同一 RestTemplate/RestClient/Feign 是否跨线程/跨 MQ 断了上下文
span 有但树是散的 parent 传播是否丢失(自研客户端) 是否在不同 trace 里各起 root span

7. 常见误区

误区 纠正
"加 Sleuth 就行" Boot 3 用 Micrometer Tracing(§2)
"traceId 会自动进所有日志" 只进被 Observation 包裹的线程;线程池/MQ 要手动透传
"100% 采样更准" 流量大时存储与网络成本线性上升,且会拖慢应用(A01)
"Zipkin 能长期存储" 默认内存存储,重启即丢;生产要接 ES/Cassandra 或换后端

8. 自测

  1. 你的 build.gradle 里有没有 micrometer-tracing-bridge-*?没有 → traceId 一定为空。
  2. 拿一条线程池任务的日志,traceId 在不在?不在 → §5.1 的 TaskDecorator。
  3. 你的采样率是多少?算出"一天能保留多少条错误链路",够不够排查。

9. 下一篇

S16-J03 · SkyWalking:Agent / OAP / UI 与服务拓扑 —— 不改代码的另一种接入方式,以及它带来的兼容性与开销代价。

S16-J02 · 接入实战:Spring Boot 3 + Micrometer Tracing + Zipkin
https://www.clxhxhhr.top/posts/5411/
作者
clxstart
发布于
2024-12-31
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。