Spring Boot 3启用分布式追踪配置问题:Trace/Span ID为空
Spring Boot 3 分布式追踪 Trace ID/Span ID 为空问题排查与解决
核心排查步骤与解决方案
1. 确认依赖完整性
你已引入micrometer-tracing-bridge-brave,但需确保:
- Web应用场景下已引入
spring-boot-starter-web(Spring Boot会自动配置Web追踪过滤器,负责初始化Span上下文) - 若需通过Actuator查看追踪指标,可补充
spring-boot-starter-actuator依赖
Maven依赖示例:
<dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-tracing-bridge-brave</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2. 启用Brave MDC集成
你的日志配置%X{traceId:-},%X{spanId:-}依赖MDC(映射诊断上下文)传递追踪ID,但Brave的MDC默认可能未完全生效,需在application.properties中添加:
brave.mdc.enabled=true brave.trace-id-continuation.enabled=true
3. 验证追踪上下文是否初始化
在业务代码中手动注入Tracer,检查Span是否正常创建:
import io.micrometer.tracing.Tracer; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TestTraceController { private final Tracer tracer; public TestTraceController(Tracer tracer) { this.tracer = tracer; } @GetMapping("/trace-test") public String testTrace() { var currentSpan = tracer.currentSpan(); if (currentSpan != null) { System.out.println("Trace ID: " + currentSpan.context().traceId()); System.out.println("Span ID: " + currentSpan.context().spanId()); } return "trace test completed"; } }
如果此处能打印出ID,说明追踪上下文正常,日志未显示可能是MDC传递问题;若打印为空,说明Span未被创建,需检查Web过滤器是否生效。
4. 异步场景的上下文传递
若使用@Async异步方法,需配置任务装饰器将追踪上下文传递到异步线程:
import io.micrometer.tracing.Tracer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.Executor; @Configuration @EnableAsync public class AsyncTraceConfig { private final Tracer tracer; public AsyncTraceConfig(Tracer tracer) { this.tracer = tracer; } @Bean("asyncExecutor") public Executor asyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(3); executor.setMaxPoolSize(5); executor.setQueueCapacity(100); executor.setThreadNamePrefix("Async-Trace-"); // 传递追踪上下文到异步线程 executor.setTaskDecorator(runnable -> { var currentContext = tracer.currentSpan() != null ? tracer.currentSpan().context() : null; return () -> { if (currentContext != null) { try (var scope = tracer.withSpan(tracer.nextSpan(currentContext))) { runnable.run(); } } else { runnable.run(); } }; }); executor.initialize(); return executor; } }
5. 排除自定义MDC干扰
检查项目中是否存在自定义的MDC过滤器或拦截器,若有需确保它们不会覆盖Brave写入的traceId和spanId字段。
内容的提问来源于stack exchange,提问作者Ramesh Talapaneni
相关产品推荐
相关产品推荐

