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

Spring Boot集成Spring Cloud Sleuth与JMS:@JmsListener追踪问题

嘿,这个问题我之前帮朋友解决过,现在Spring Cloud Sleuth早就支持JMS的链路追踪了,你遇到的情况大概率是依赖版本或者配置的小问题,我给你一步步捋清楚怎么搞定:

解决Spring Cloud Sleuth对@JmsListener的追踪问题

1. 先确认依赖版本是否达标

早期的Sleuth版本(比如2016-2017年的版本)确实对JMS的支持不完善,但从**Spring Cloud Hoxton版本(对应Spring Boot 2.2+)**开始,Sleuth已经内置了对JMS的自动追踪支持。所以第一步要检查你的依赖版本:

  • 如果你用Maven,确保spring-cloud-starter-sleuth和spring-cloud-starter-zipkin(如果需要链路可视化)的版本和Spring Cloud版本匹配:
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
  • Gradle项目的话,依赖配置是这样:
implementation 'org.springframework.cloud:spring-cloud-starter-sleuth'
implementation 'org.springframework.cloud:spring-cloud-starter-zipkin'

2. 确保消息生产者传递追踪头

Sleuth会自动在JMS消息属性里注入X-B3-TraceId、X-B3-SpanId这些追踪标识,但前提是你用Spring的JmsTemplate发送消息——它会被Sleuth自动拦截并添加追踪头。如果是手动构造消息发送,就得手动把当前追踪上下文的信息塞进消息属性里:

@Autowired
private Tracer tracer;

@Autowired
private JmsTemplate jmsTemplate;

public void sendJmsMessage(String destination, String content) {
    Span currentSpan = tracer.currentSpan();
    if (currentSpan != null) {
        jmsTemplate.send(destination, session -> {
            TextMessage textMessage = session.createTextMessage(content);
            // 注入B3追踪头
            textMessage.setStringProperty("X-B3-TraceId", currentSpan.context().traceId());
            textMessage.setStringProperty("X-B3-SpanId", currentSpan.context().spanId());
            textMessage.setStringProperty("X-B3-Sampled", "1"); // 标记为需要采样
            return textMessage;
        });
    } else {
        // 没有追踪上下文时直接发送
        jmsTemplate.convertAndSend(destination, content);
    }
}

3. 开启Sleuth的JMS支持(默认已开启,保险起见检查下)

在新版本中,Sleuth默认已经启用了JMS追踪,但如果你的配置里不小心禁用了,可以在application.yml里明确开启:

spring:
  sleuth:
    jms:
      enabled: true

4. 自定义JMS监听器的追踪逻辑(可选)

如果默认的追踪信息不够用,比如想自定义span名称、添加业务标签,可以实现SpanAdjuster接口来扩展:

@Component
public class CustomJmsSpanAdjuster implements SpanAdjuster {
    @Override
    public Span adjust(Span span, Message message) {
        // 把span名称改成更有业务意义的名字
        return span.name("jms-listener-" + message.getJMSDestination())
                .tag("message-type", message.getClass().getSimpleName())
                .tag("destination", message.getJMSDestination().toString());
    }
}

5. 排查常见坑点

  • 检查是否有其他JMS拦截器覆盖了Sleuth的拦截器,确保Sleuth的JMS拦截器优先级更高;
  • 确认你的@JmsListener所在的类是Spring管理的Bean,已经被容器扫描到;
  • 如果用的是ActiveMQ这类特定JMS实现,要确认没有禁用自定义消息属性的传递——有些MQ默认会过滤非标准属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 06:53:58