使用CompletableFuture时Tracing Context未传播的问题排查求助
Spring Boot 3.2.4中CompletableFuture的追踪上下文传播问题解决
你的问题核心是手动构建的ContextSnapshotFactory没有包含Micrometer追踪上下文的传播器,导致捕获的上下文快照里没有TraceContext,异步线程无法获取到追踪信息。
解决方法
方案1:使用Spring自动配置的ContextSnapshotFactory
Spring Boot已经为我们配置好了包含TraceContext传播器的ContextSnapshotFactory,直接注入使用即可:
@Autowired private ContextSnapshotFactory contextSnapshotFactory; @Test void testContextPropagation() throws ExecutionException, InterruptedException { // 使用try-with-resources确保Span自动结束 try (ScopedSpan scopedSpan = tracer.startScopedSpan("trigger the creation of a new trace...")) { logger.info("CONTEXT: {}", tracer.currentTraceContext().context()); Executor wrappedExecutor = contextSnapshotFactory.captureAll().wrapExecutor(Executors.newSingleThreadExecutor()); CompletableFuture.supplyAsync(() -> { logger.info("CONTEXT: {}", tracer.currentTraceContext().context()); return null; }, wrappedExecutor).get(); } }
方案2:手动为ContextSnapshotFactory添加TraceContext传播器
如果必须手动构建工厂,需要显式添加TraceContextPropagator:
@Test void testContextPropagation() throws ExecutionException, InterruptedException { try (ScopedSpan scopedSpan = tracer.startScopedSpan("trigger the creation of a new trace...")) { logger.info("CONTEXT: {}", tracer.currentTraceContext().context()); ContextSnapshotFactory factory = ContextSnapshotFactory.builder() .propagators(TraceContextPropagator.getInstance()) .build(); Executor wrappedExecutor = factory.captureAll().wrapExecutor(Executors.newSingleThreadExecutor()); CompletableFuture.supplyAsync(() -> { logger.info("CONTEXT: {}", tracer.currentTraceContext().context()); return null; }, wrappedExecutor).get(); } }
补充说明
- 建议用
try-with-resources管理ScopedSpan,避免因异常导致Span无法正常结束,影响追踪数据准确性。 - 若需要传播Baggage,上述两种方案同样适用,因为
TraceContextPropagator已经包含了Baggage的传播逻辑。
内容的提问来源于stack exchange,提问作者François Rosière
相关产品推荐
相关产品推荐

