Spring Boot3中WebClient用Brave时生成新TraceId的问题排查
问题描述
我正在创建一个Spring Boot 3服务,需要与Spring Boot 2 Sleuth服务交互。已配置该Spring Boot 3应用通过WebClient传播B3 TraceId,但WebClient生成了另一个TraceId,未传播原有TraceId。
执行流程:访问http://localhost:8080端点,该端点会调用http://localhost:9090。
核心业务代码
@RestController @SpringBootApplication public class MyApplication { private static final Log logger = LogFactory.getLog(MyApplication.class); @Autowired WebClient.Builder builder; @RequestMapping("/") String home() { logger.info("Testing sending request to client"); String data = builder .baseUrl("http://localhost:9090") .exchangeStrategies(ExchangeStrategies.builder().codecs(c -> c.defaultCodecs().enableLoggingRequestDetails(true)).build() ) .build() .get() .exchangeToMono(res -> res.bodyToMono(String.class)) .block(); return data; } }
B3追踪配置类
@Configuration public class Config { @Bean public Tracing braveTracing() { return Tracing.newBuilder() .propagationFactory( B3Propagation.newFactoryBuilder() .injectFormat(B3Propagation.Format.MULTI) .build()) .build(); } }
配置文件(application.properties)
spring.application.name=demo logging.level.org.springframework.web=TRACE #spring.mvc.log-request-details=true #spring.http.log-request-details=true spring.codec.log-request-details=true management.tracing.propagation.type=B3 logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions=TRACE management.tracing.enabled = true management.tracing.sampling.probability = 1.0
Build.gradle依赖
implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'io.micrometer:micrometer-tracing-bridge-brave' implementation 'org.springframework.boot:spring-boot-starter-webflux' testImplementation 'org.springframework.boot:spring-boot-starter-test'
日志输出
2024-04-16T15:10:27.010-04:00 TRACE 34890 --- [demo] [nio-8080-exec-1] [121d49ff22764a67 -121d49ff22764a67] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.example.demo.MyApplication#home() 2024-04-16T15:10:27.027-04:00 TRACE 34890 --- [demo] [nio-8080-exec-1] [121d49ff22764a67 -121d49ff22764a67] o.s.web.method.HandlerMethod : Arguments: [] 2024-04-16T15:10:27.028-04:00 INFO 34890 --- [demo] [nio-8080-exec-1] [121d49ff22764a67 -121d49ff22764a67] com.example.demo.MyApplication : Testing sending request to client 2024-04-16T15:10:27.138-04:00 TRACE 34890 --- [demo] [nio-8080-exec-1] [121d49ff22764a67 -121d49ff22764a67] o.s.w.r.f.client.ExchangeFunctions : [2f40d44] HTTP GET http://localhost:9090, headers=[X-B3-TraceId:"8089985fbcccddfa", X-B3-SpanId:"8089985fbcccddfa", X-B3-Sampled:"1"]
从日志可见,Spring Boot 3应用自身的TraceId为121d49ff22764a67,但WebClient发起请求时传播的却是8089985fbcccddfa,需解决WebClient传播原有TraceId的问题。
解决方案
问题根源在于自定义的Tracing Bean,手动创建的Tracing实例未与Spring Boot的Micrometer Tracing上下文集成,导致WebClient无法获取当前线程的TraceId,进而生成新的TraceId。
修改步骤:
- 移除自定义的
Config类:Spring Boot会根据配置自动生成符合B3规范的Tracing实例,无需手动创建。 - 保留自动配置的WebClient.Builder:当前代码已正确注入
WebClient.Builder,无需修改,避免手动覆盖追踪相关配置。 - 验证配置项:确保
management.tracing.propagation.type=B3配置正确,该配置会自动启用B3格式的追踪传播。
修改完成后,WebClient会自动从当前请求上下文获取TraceId并传播,不再生成新的TraceId。
额外优化建议
避免在Spring MVC控制器中使用.block()阻塞调用WebClient,违背WebFlux非阻塞设计。建议将控制器方法改为返回Mono<String>:
@RequestMapping("/") Mono<String> home() { logger.info("Testing sending request to client"); return builder .baseUrl("http://localhost:9090") .exchangeStrategies(ExchangeStrategies.builder().codecs(c -> c.defaultCodecs().enableLoggingRequestDetails(true)).build() ) .build() .get() .exchangeToMono(res -> res.bodyToMono(String.class)); }
既保持非阻塞特性,也能确保追踪上下文正确传递。
内容的提问来源于stack exchange,提问作者david
相关产品推荐
相关产品推荐

