必须使用spring-boot-starter-activemq-jakarta 4.1.0,配置failover集群url并禁用randomize,手动创建boot.queue队列,移除旧池化依赖,确保activemq artemis集群的network connectors处于active状态。

要在SpringBoot 4.1项目中完成ActiveMQ Starter的集成并支持集群部署,必须避开Spring Boot 3.x起废弃的auto-configuration路径,同时解决ActiveMQ 6.x新版本对JMS 2.0.3+的强制要求,否则启动时会抛出javax.jms.JMSException: Not a valid JMS destination异常。
确认ActiveMQ服务端已就绪
访问 http://localhost:8161/admin,使用默认账号 admin/admin 登录管理后台。若页面无法打开,说明ActiveMQ未运行或端口被占用——【必须确保8161(控制台)和61616(OpenWire协议)端口均处于监听状态】。
在Queues标签页下,手动创建一个名为 BOOT.QUEUE 的队列,不勾选“Temporary”,点击“Create”。这一步不能跳过,Spring Boot 4.1默认不再自动创建队列,仅支持连接已存在的目标。
检查左侧导航栏是否显示 “Network Connectors” 且状态为 “Active”。若无此选项或显示 “Disabled”,说明当前运行的是单节点模式,不满足集群前提条件。
引入适配Spring Boot 4.1的Starter依赖
在 pom.xml 中替换旧版 starter,使用官方维护的 Jakarta EE 兼容版本:
删除所有含 activemq-pool 或 pooled-jms 的依赖项——Spring Boot 4.1内置连接池已重构为 org.apache.activemq.artemis.jms.client.ActiveMQJMSConnectionFactory,旧池化实现与Jakarta命名空间冲突,会导致 BeanCreationException。
如果项目中存在自定义 JmsTemplate Bean 定义,必须移除或重命名为非默认名(如 customJmsTemplate),否则会覆盖 Spring Boot 4.1 自动配置的 Jakarta 兼容实例。
配置application.yml启用集群连接
使用 YAML 格式,严格区分空格缩进,不可混用 Tab:
spring:
activemq:
broker-url: failover:(tcp://192.168.1.10:61616,tcp://192.168.1.11:61616,tcp://192.168.1.12:61616)?randomize=false&initialReconnectDelay=500&maxReconnectDelay=30000
user: admin
password: admin
jms:
pub-sub-domain: false
template:
default-destination: BOOT.QUEUE
【failover URL 中的 randomize=false 是关键,否则集群节点间负载不均,消息可能卡在某一台Broker上无法投递】
broker-url 中三个 IP 必须对应实际部署的 ActiveMQ Artemis 集群节点地址;若使用传统 ActiveMQ 5.x,需先升级至 5.18.3+ 并启用 networkConnector 配置,否则 failover 机制无法识别集群拓扑。
声明队列并注入JmsTemplate
方法一:通过 @Bean 声明标准 Queue 实例
@Configuration
public class JmsQueueConfig {
@Bean
public Queue bootQueue() {
return new ActiveMQQueue("BOOT.QUEUE");
}
}
方法二:使用 @Value 绑定配置属性(更推荐)
@Configuration
public class JmsQueueConfig {
@Value("${spring.jms.template.default-destination}")
private String queueName;
@Bean
public Queue bootQueue() {
return new ActiveMQQueue(queueName);
}
}
注意:不要在 @JmsListener 注解中直接写死队列名,例如 @JmsListener(destination = "BOOT.QUEUE") —— 这会导致监听器绑定到本地内存队列而非集群Broker,消息将无法跨节点消费。
编写生产者发送消息
第一步:注入 Jakarta 兼容的 JmsTemplate
@Autowired
private JmsTemplate jmsTemplate;
第二步:构造消息并发送
String payload = "order-id-202608061702";
jmsTemplate.convertAndSend("BOOT.QUEUE", payload);
第三步:验证发送结果
登录 ActiveMQ 控制台 → Queues → 点击 BOOT.QUEUE → 查看 “Number Of Pending Messages” 是否 +1。若为 0,检查日志中是否有 “Failed to connect to broker” 或 “Destination does not exist” 错误。
第四步:添加消息头以支持集群路由
MessagePostProcessor postProcessor = message -> {
message.setJMSXGroupID("GROUP-A");
message.setStringProperty("cluster-route", "shard-1");
return message;
};
jmsTemplate.convertAndSend("BOOT.QUEUE", payload, postProcessor);











