当前位置: 首页 > news >正文

Spring Boot接入链路追踪(Micrometer Tracing+Zipkin) 一

分布式追踪集成:自动透传 TraceID 1. 使用 Micrometer Tracing(Spring Boot 3+ 推荐)

在 Spring Boot 3.x + Spring Cloud 2022+(如 2023.0.x)中,
Spring Cloud Sleuth 已被弃用,官方推荐使用 Micrometer Tracing(基于 Brave 或 OpenTelemetry)来实现分布式追踪,包括自动透传 traceId 和 spanId,并将其注入到日志的 MDC 中,供日志系统(如 ELK、Loki)使用。

✅ 一、依赖管理(更完整的配置)

Maven (pom.xml)

xml

<?xml version="1.0" encoding="UTF-8"?>
<project><properties><micrometer-tracing.version>1.2.0</micrometer-tracing.version><zipkin-reporter.version>2.16.3</zipkin-reporter.version></properties><dependencies><!-- Micrometer Tracing with Brave --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId></dependency><!-- Brave 传播器 --><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId></dependency><!-- Zipkin 报告器 --><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId><version>${zipkin-reporter.version}</version></dependency><!-- HTTP 发送器 --><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-sender-okhttp3</artifactId><version>${zipkin-reporter.version}</version></dependency><!-- 日志结构化 --><dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>7.4</version></dependency><!-- Web 客户端支持(必须,用于 HTTP 调用追踪) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Actuator(必须,用于追踪端点) --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies><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>
</project>

Gradle (build.gradle)

gradle

ext {micrometerTracingVersion = '1.2.0'zipkinReporterVersion = '2.16.3'
}dependencies {// Micrometer Tracingimplementation 'io.micrometer:micrometer-tracing-bridge-brave'implementation 'io.micrometer:micrometer-tracing'// Zipkinimplementation "io.zipkin.reporter2:zipkin-reporter-brave:${zipkinReporterVersion}"implementation "io.zipkin.reporter2:zipkin-sender-okhttp3:${zipkinReporterVersion}"// 日志implementation 'net.logstash.logback:logstash-logback-encoder:7.4'// Spring Bootimplementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.springframework.boot:spring-boot-starter-actuator'
}dependencyManagement {imports {mavenBom "io.micrometer:micrometer-tracing-bom:${micrometerTracingVersion}"}
}

✅ 二、详细配置(application.yml)

yaml

spring:application:name: order-service# Sleuth 兼容配置(可选)sleuth:enabled: false  # 明确禁用 Sleuth# Micrometer Tracing 配置
management:tracing:enabled: truesampling:probability: 1.0  # 采样率:1.0=100%, 0.1=10%# 传播类型配置propagation:type: W3C  # 支持:W3C, B3, B3_MULTI# Brave 特定配置brave:sampler:rate: 10000  # 每秒最大采样数# Actuator 端点endpoints:web:exposure:include: health,metrics,info,tracecontext# Zipkin 配置(可选)
zipkin:base-url: http://localhost:9411enabled: truesender:type: web  # 使用 HTTP 发送# 日志配置
logging:pattern:level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"level:io.micrometer.tracing: DEBUG  # 调试时可开启

✅ 三、增强的 Logback 配置

logback-spring.xml

xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration><include resource="org/springframework/boot/logging/logback/defaults.xml"/><!-- JSON 格式输出 --><appender name="JSON_CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"><providers><timestamp><timeZone>UTC</timeZone></timestamp><logLevel/><loggerName/><message/><pattern><pattern>{"service": "${spring.application.name:-unknown}"}</pattern></pattern><mdc><!-- 包含所有 MDC 字段 --><includeMdcKeyName>traceId</includeMdcKeyName><includeMdcKeyName>spanId</includeMdcKeyName><includeMdcKeyName>parentId</includeMdcKeyName><includeMdcKeyName>service.name</includeMdcKeyName></mdc><threadName/><stackTrace><throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"><maxDepthPerThrowable>30</maxDepthPerThrowable><maxLength>2048</maxLength><shortenedClassNameLength>20</shortenedClassNameLength><rootCauseFirst>true</rootCauseFirst></throwableConverter></stackTrace></providers></encoder></appender><!-- 传统格式输出(开发环境) --><appender name="PLAIN_CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId:-},%X{spanId:-}] %logger{36} - %msg%n</pattern></encoder></appender><!-- 根据 profile 选择输出格式 --><springProfile name="dev | local"><root level="INFO"><appender-ref ref="PLAIN_CONSOLE"/></root></springProfile><springProfile name="!dev &amp; !local"><root level="INFO"><appender-ref ref="JSON_CONSOLE"/></root></springProfile><!-- 特定包日志级别 --><logger name="com.yourcompany" level="DEBUG"/><logger name="org.springframework.web" level="INFO"/><logger name="io.micrometer.tracing" level="INFO"/>
</configuration>

✅ 四、验证和测试控制器

java

@RestController
@Slf4j
public class TraceDemoController {private final RestTemplate restTemplate;private final Tracer tracer;public TraceDemoController(RestTemplateBuilder restTemplateBuilder, Tracer tracer) {this.restTemplate = restTemplateBuilder.build();this.tracer = tracer;}@GetMapping("/demo")public String demoTrace() {log.info("收到请求 - 开始处理");// 当前追踪信息Span currentSpan = tracer.currentSpan();if (currentSpan != null) {log.info("TraceId: {}, SpanId: {}", currentSpan.context().traceId(),currentSpan.context().spanId());}// 模拟业务处理processBusiness();log.info("请求处理完成");return "Trace ID: " + (currentSpan != null ? currentSpan.context().traceId() : "null");}@GetMapping("/call-downstream")public String callDownstream() {log.info("调用下游服务开始");// 自动携带追踪头调用下游服务String result = restTemplate.getForObject("http://localhost:8081/demo", String.class);log.info("下游服务调用完成: {}", result);return "Called downstream: " + result;}private void processBusiness() {log.debug("处理业务逻辑...");// 业务代码}
}

✅ 五、配置类(确保正确配置)

java

@Configuration
public class TracingConfig {@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {return builder.build();}@Beanpublic Sampler alwaysSampler() {return Sampler.ALWAYS_SAMPLE;}
}

✅ 六、异步任务中的追踪处理

java

@Service
@Slf4j
public class AsyncService {private final Tracer tracer;private final ObservationRegistry observationRegistry;public AsyncService(Tracer tracer, ObservationRegistry observationRegistry) {this.tracer = tracer;this.observationRegistry = observationRegistry;}// 方法1:使用 Observation(推荐)@Asyncpublic CompletableFuture<String> processAsync(String data) {return Observation.createNotStarted("async-process", observationRegistry).observe(() -> {log.info("异步处理数据: {}", data);// 模拟处理try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}log.info("异步处理完成");return CompletableFuture.completedFuture("processed: " + data);});}// 方法2:手动传播上下文@Asyncpublic void manualAsyncProcess() {// 获取当前上下文Span currentSpan = tracer.currentSpan();if (currentSpan != null) {// 在新的线程中手动设置上下文try (Tracer.SpanInScope scope = tracer.withSpan(currentSpan)) {log.info("手动传播的异步任务");// 业务逻辑}} else {log.info("没有追踪上下文的异步任务");}}
}

✅ 七、Feign Client 集成

java

@FeignClient(name = "payment-service", url = "http://localhost:8082")
public interface PaymentClient {@GetMapping("/payment")String processPayment();
}// 自动支持追踪,无需额外配置

✅ 八、常见问题解决方案

1. 自定义 HTTP 客户端追踪

java

@Bean
public RestTemplate tracedRestTemplate() {RestTemplate restTemplate = new RestTemplate();// 添加追踪拦截器List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();interceptors.add(new TracingClientHttpRequestInterceptor(tracer));restTemplate.setInterceptors(interceptors);return restTemplate;
}

2. 手动记录 Span

java

@Autowired
private Tracer tracer;public void manualSpan() {Span span = tracer.nextSpan().name("custom-operation").start();try (Tracer.SpanInScope scope = tracer.withSpan(span)) {span.event("操作开始");log.info("执行自定义操作");// 业务逻辑span.tag("result", "success");} catch (Exception e) {span.tag("result", "error");span.error(e);throw e;} finally {span.end();}
}

✅ 九、健康检查端点

访问 http://localhost:8080/actuator/tracecontext 查看当前追踪上下文:

json

{"traceId": "a1b2c3d4e5f6a7b8","spanId": "c9d0e1f2a3b4c5d6","parentId": null,"sampled": true
}

✅ 十、完整的日志输出示例

json

{"@timestamp": "2024-01-15T10:30:00.123Z","level": "INFO","logger": "com.example.TraceDemoController","message": "收到请求 - 开始处理","service": "order-service","traceId": "a1b2c3d4e5f6a7b8","spanId": "c9d0e1f2a3b4c5d6","thread": "http-nio-8080-exec-1"
}

这个方案提供了:

  • ✅ 完整的依赖配置

  • ✅ 详细的配置文件

  • ✅ 多种日志格式支持

  • ✅ 异步任务追踪

  • ✅ 常见问题解决方案

  • ✅ 验证和测试方法

http://www.dtcms.com/a/478601.html

相关文章:

  • Jenkins Share Library教程 —— 开发入门
  • SpringBoot读取自定义格式的Nacos配置
  • WordPress建站怎么交付青岛seo网络推广
  • 江西个人网站备案小制作小发明简单做法
  • 在Qt中实现SwitchButton(开关按钮)
  • day9_elementPlus2
  • qiankun子应用使用elementUI操作反馈图标不显示
  • Vue3.0: v-model 组件双向绑定学习文档 (v3.4 前后对比 + TypeScript)
  • 中山哪里有做微网站的做ppt图片用的网站
  • 『 QT 』QT窗口坐标体系详解
  • 服务器里怎么建设网站网站开发网站设计素材
  • 从多个数据源(CSV, Excel, SQL)自动整合数据
  • 智慧零售天气预知可视化监控平台
  • C++设计模式_结构型模式_享元模式Flyweight
  • 网站备案名称能重复吗微官网怎么制作
  • SpringBoot + MyBatis 注解开发入门实践
  • Java EE初阶--多线程
  • 深入理解梯度消失:从DNN到RNN的全面解析与解决方案
  • 南京电子商务网站开发公司石油化工工程建设人才招聘网站
  • 大数据实战:Python+Flask 汽车数据分析可视化系统(爬虫+线性回归预测+推荐 源码+文档)✅
  • 算法8.0
  • 网站左侧导航栏设计一个网站的建设要经过哪几个阶段
  • Java-Linux环境下查看JDK安装路径
  • 嘉立创学习
  • QML学习笔记(三十四)QML的GroupBox、RadioButton
  • AI Agent 的技术架构、产业赋能与治理挑战研究 —— 基于 2024-2025 年技术突破与应用实践的分析
  • 设计美观网站有哪些辽宁网站建设价位
  • vtkFillHolesFilter——3D网格补孔的“一键修复”工具,从原理到避坑
  • 网站建设完整代码深圳开公司流程及费用
  • Vue3为什么选择用Vite?使用指南与优势解析