Spring Boot 2与Spring Boot 3应用及Kafka链路追踪实现问题
跨版本Spring Boot链路追踪(Sleuth ↔ Micrometer Tracing)解决方案
核心问题在于Spring Boot 2的Sleuth与Spring Boot 3的Micrometer Tracing默认的Trace ID传播协议兼容配置,以及Kafka链路的头信息传递处理,以下是具体实现方案:
一、统一Trace ID传播协议(B3格式)
Sleuth原生支持B3协议,Micrometer Tracing默认以W3C为主,但可兼容B3,需两边配置统一:
1. Spring Boot 2(Sleuth)配置
Sleuth默认已启用B3,可显式配置确保:
spring.sleuth.propagation.type=B3
2. Spring Boot 3(Micrometer Tracing)配置
启用B3传播格式,支持与Sleuth的Trace ID互通:
management.tracing.propagation.type=B3 # 如需同时兼容W3C,可配置为:management.tracing.propagation.type=W3C,B3
二、HTTP请求链路的Trace ID传递
1. Spring Boot 2 → Spring Boot 3
Sleuth会自动为RestTemplate/WebClient注入X-B3-TraceId、X-B3-SpanId等B3头,Spring Boot 3端只要配置了B3传播,就能自动解析并复用Trace ID。
若使用自定义HTTP客户端,需手动传递头信息:
// Spring Boot 2中获取Trace ID @Autowired private Tracer tracer; String traceId = tracer.currentSpan().context().traceId(); String spanId = tracer.currentSpan().context().spanId(); // 手动添加HTTP头 HttpHeaders headers = new HttpHeaders(); headers.set("X-B3-TraceId", traceId); headers.set("X-B3-SpanId", spanId); headers.set("X-B3-Sampled", "1"); HttpEntity<Void> entity = new HttpEntity<>(headers); restTemplate.exchange("http://sb3-app/api", HttpMethod.GET, entity, String.class);
2. Spring Boot 3 → Spring Boot 2
Micrometer Tracing会自动为RestTemplate/WebClient注入B3头,Sleuth端可直接解析。手动获取Trace ID方式:
// Spring Boot 3中获取Trace ID @Autowired private io.micrometer.tracing.Tracer tracer; String traceId = tracer.currentSpan().context().traceId();
三、Kafka消息链路的Trace ID传递
这是你当前场景的核心卡点,需确保Kafka消息头携带B3信息,且两边能正确解析:
1. Spring Boot 2(生产者)配置
确保依赖包含Sleuth与Spring Kafka,Sleuth会自动拦截生产者,注入B3头到消息中:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency>
2. Spring Boot 3(消费者)配置
引入Micrometer Tracing的Brave桥接依赖,并配置Kafka消费者拦截器解析B3头:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency> <dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> </dependency>
添加消费者配置:
spring.kafka.consumer.properties.interceptor.classes=io.micrometer.tracing.brave.kafka.BraveKafkaConsumerTracingInterceptor
3. 代码中手动获取Trace ID
- Spring Boot 2:通过Sleuth的
Tracer实例获取,同HTTP场景。 - Spring Boot 3:通过Micrometer的
Tracer实例获取,同HTTP场景。
四、日志统一输出Trace ID
确保两边日志配置中打印Trace ID,便于链路排查:
Spring Boot 2(logback.xml)
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg [%X{X-B3-TraceId}/%X{X-B3-SpanId}]%n</pattern> </encoder>
Spring Boot 3(logback.xml)
<encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg [%X{traceId}/%X{spanId}]%n</pattern> </encoder>
五、验证流程
- 启动两端应用,确认配置生效。
- 发送HTTP请求到Spring Boot 2应用,检查日志中的Trace ID。
- 查看Kafka消息头,确认包含
X-B3-TraceId字段。 - Spring Boot 3消费消息后,检查日志是否输出相同的Trace ID。
内容的提问来源于stack exchange,提问作者Eygonb
相关产品推荐
相关产品推荐

