Artemis ActiveMQ嵌入式模式在Spring Boot集成测试中无法接收消息,原生模式正常
解决Spring Boot集成测试中Artemis嵌入式模式收不到消息的问题
嘿,我之前在做Spring Boot集成测试时也踩过Artemis嵌入式模式的坑,结合你的情况,给你几个实用的排查和解决方向:
1. 最常见的坑:配置冲突导致连接到外部Broker
你在application-test.properties里同时配置了spring.artemis.mode=embedded和host/port,这会出问题!
嵌入式Artemis是内存内运行的Broker,不需要通过网络连接。当你指定host=localhost和port=61616时,JMS客户端会尝试连接外部的Artemis服务,而不是你启动的嵌入式实例。
修复方法:
修改测试配置,移除或清空host/port配置:
spring.artemis.mode=embedded spring.artemis.user=exampleuser spring.artemis.password=examplepassword spring.artemis.embedded.topics=example-topic # 确保topic名称完整 # 去掉host和port,或者设置为无效值 # spring.artemis.host= # spring.artemis.port=0
2. 消息接收的同步时机问题
集成测试中,发送消息后可能嵌入式Broker还没完成消息路由,你的接收逻辑就已经执行了,导致看起来“收不到”。
解决方法:
- 使用
JmsTemplate的超时接收:
@Autowired private JmsTemplate jmsTemplate; @Test void testEmbeddedArtemisSendReceive() throws InterruptedException { String testMsg = "Test Embedded Message"; // 发送消息到指定topic jmsTemplate.send("example-topic", session -> session.createTextMessage(testMsg)); // 设置5秒超时接收,确保Broker有足够时间处理 Message receivedMsg = jmsTemplate.receive("example-topic", 5000); assertNotNull("未收到消息", receivedMsg); assertEquals(testMsg, ((TextMessage) receivedMsg).getText()); }
- 如果用
@JmsListener注解的监听器,要确保监听器已经完成注册,可在测试类上添加@DirtiesContext来保证每次测试都刷新上下文,或者用CountDownLatch同步监听器的消息接收:
private CountDownLatch latch = new CountDownLatch(1); private String receivedMessage; @JmsListener(destination = "example-topic") public void onMessage(TextMessage message) throws JMSException { receivedMessage = message.getText(); latch.countDown(); } @Test void testListenerReceive() throws InterruptedException { jmsTemplate.send("example-topic", session -> session.createTextMessage("Hello Listener")); // 等待监听器接收消息,超时10秒 assertTrue(latch.await(10, TimeUnit.SECONDS)); assertEquals("Hello Listener", receivedMessage); }
3. 嵌入式Broker的核心配置检查
- 确认topic/队列配置完整:你的配置里
spring.artemis.embedded.topics=example...要补全完整的topic名称,比如example-topic;如果是队列,要用spring.artemis.embedded.queues。 - 持久化设置:嵌入式模式默认是内存非持久化(
spring.artemis.embedded.persistent=false),如果你的消息是持久化类型,但测试中没有持久化存储,可能导致消息丢失。测试场景下建议保持非持久化,避免不必要的存储问题。
4. 依赖冲突排查
确保测试依赖只引入了Artemis相关的starter,不要同时混入原生ActiveMQ的依赖,避免类加载冲突:
<!-- 正确的测试依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-artemis</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-server</artifactId> <scope>test</scope> </dependency>
先试试去掉host/port的配置,这大概率是你遇到的问题!
内容的提问来源于stack exchange,提问作者Abder KRIMA
相关产品推荐
相关产品推荐

