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

Spring Boot中@SqsListener注解方法日志缺失TraceId问题咨询

问题根因

@SqsListener的消息处理线程由AWS SQS SDK独立维护,默认没有接入Spring Cloud Sleuth的链路上下文传播机制。Sleuth的TraceId、SpanId默认存储在线程本地变量(ThreadLocal)中,跨线程传递链路信息时没有对应钩子做传递,就会出现监听方法内链路ID丢失的问题。

解决方案

方案1:启用Sleuth对AWS SQS的原生支持(适用Sleuth 3.x+版本)

  • 确认Spring Cloud Sleuth版本在3.0及以上,该版本已经内置了对spring-cloud-aws的SQS集成支持
  • 引入Sleuth的AWS集成依赖即可,Maven配置示例:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-integration-aws</artifactId>
</dependency>
  • 无需额外代码配置,依赖引入后Sleuth会自动给@SqsListener方法添加链路传播切面,自动从SQS消息属性中读取链路信息,没有的话会自动生成新的链路ID,打印日志时会自动携带。

方案2:手动传递链路上下文(低版本Sleuth适配方案)

如果使用的是Sleuth 2.x等低版本,没有内置SQS集成,可通过自定义切面拦截所有@SqsListener修饰的方法,在方法执行前初始化链路上下文:

@Aspect
@Component
public class SqsListenerTraceAspect {
    private final Tracer tracer;

    public SqsListenerTraceAspect(Tracer tracer) {
        this.tracer = tracer;
    }

    @Around("@annotation(org.springframework.cloud.aws.messaging.listener.annotation.SqsListener)")
    public Object wrapSqsListenerTrace(ProceedingJoinPoint pjp) throws Throwable {
        // 尝试从消息属性中获取已有的TraceId,没有的话新建链路
        Span span = tracer.nextSpan().name("sqs-receive").start();
        try (Tracer.SpanInScope ignored = tracer.withSpan(span)) {
            return pjp.proceed();
        } finally {
            span.end();
        }
    }
}
  • 如果需要上下游链路打通,只需要在发送SQS消息时,将当前TraceId、SpanId放到消息属性中,拦截器中读取对应属性构建Span即可。

方案3:配置SQS线程池接入Sleuth装饰器

如果自定义了SQS的监听线程池,需要给线程池添加Sleuth的线程装饰器,确保所有线程池调度的任务都自动传递链路上下文:

@Bean
public AsyncTaskExecutor sqsListenerExecutor(TraceRunnableDecorator traceDecorator) {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(100);
    executor.setThreadNamePrefix("sqs-listener-");
    // 关键:添加Sleuth的链路装饰器
    executor.setTaskDecorator(traceDecorator);
    executor.initialize();
    return executor;
}
验证方式

在@SqsListener方法内打印日志,确认日志中已经出现traceId、spanId字段即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 12:03:02