You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CompletableFuture.handle时OpenTelemetry链路追踪丢失求助

解决OpenTelemetry在CompletableFuture.handle中链路追踪丢失问题

问题原因

CompletableFuture的异步回调默认不会自动传播OpenTelemetry的Context,线程切换时上下文无法传递到回调逻辑中,导致Trace丢失。另外如果未正确引入CompletableFuture的自动插桩依赖,也会导致上下文无法自动传播。

解决方案

1. 确保引入CompletableFuture自动插桩依赖

OpenTelemetry提供了专门的CompletableFuture插桩模块,用于自动处理上下文传播。如果使用Maven,添加以下依赖:

<dependency>
    <groupId>io.opentelemetry.instrumentation</groupId>
    <artifactId>opentelemetry-instrumentation-completable-future</artifactId>
    <version>适配你的OpenTelemetry版本</version>
    <scope>runtime</scope>
</dependency>

如果是Spring Boot项目,也可通过opentelemetry-spring-boot-starter间接引入,但需确保版本兼容。

2. 手动上下文传播(自动插桩不生效时备用)

如果自动插桩无法生效,可手动在主线程保存当前上下文,然后用Context.wrap包裹回调函数,强制传递上下文:

@GetMapping("/future3")
public CompletableFuture<ResponseEntity<String>> future3() {
    LOGGER.info("future1 ");
    LOGGER.info("trace={}", Span.current().getSpanContext().getTraceId());

    // 保存主线程的OpenTelemetry上下文
    Context currentContext = Context.current();

    SqsAsyncClient sqsAsyncClient = SqsAsyncClient.builder().build(); 
    CompletableFuture<ResponseEntity<String>> aa = sqsAsyncClient
        .sendMessage(build -> build.queueUrl(queueUrl).messageBody("hello"))
        // 用Context.wrap包裹回调,传递上下文
        .handle(Context.wrap(currentContext, (response, error) -> {
            LOGGER.info("trace response={}", Span.current().getSpanContext().getTraceId());
            LOGGER.info("test response={}", response);
            return new ResponseEntity<>("success", HttpStatus.OK);
        }));
    LOGGER.info("future1_1");
    return aa;
}

3. 验证SqsAsyncClient插桩生效

确保SqsAsyncClient的调用已被OpenTelemetry追踪,这样sendMessage生成的Span会自动关联到主线程的Trace中,形成完整链路。可通过检查Trace数据是否包含SQS调用的Span来验证。

内容的提问来源于stack exchange,提问作者user1684689

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:10:07