ActiveMQ Artemis控制台无法查看Pub/Sub消息及相关JMS疑问
JMS + ActiveMQ Artemis 实践问题整理
背景
正在学习JMS,使用Felipe Gutierrez所著《Spring Boot Messaging》(2017版)。书中基于Apache ActiveMQ讲解Java/Spring Boot消息通信,说明代码可适配其他消息中间件,因此安装了ActiveMQ Artemis。
代码实现
配置类
@Configuration public class JmsConfig { @Bean public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_class_"); // 自定义类型标识属性,生产者消费者需保持一致 return converter; } }
Sender类
@Component public class Sender { private final JmsTemplate jmsTemplate; public Sender(JmsTemplate jmsTemplate){ this.jmsTemplate = jmsTemplate; } public void sendMessage(String destination, String message){ this.jmsTemplate.convertAndSend("test-destination", message); } }
Receiver类
.... @JmsListener(destination = "test-destinaton") public void consumeTopicOne(String message) { log.info("Received Message Queue/Topic1: " + message); } ....
application.properties 配置
spring.artemis.mode=native spring.artemis.embedded.enabled=false spring.artemis.broker-url=tcp://localhost:61616 spring.artemis.user=admin spring.artemis.password=admin spring.jms.pub-sub-domain=false
注:主类未添加
@EnableJms注解。
当前现象
- 点对点(Queue)模式:仅注释Receiver代码后,才能在控制台看到消息;
- 发布/订阅(Pub/Sub)模式(设置
spring.jms.pub-sub-domain=true):消息能正常发送接收,但无论是否注释Receiver,控制台都看不到消息。
疑问
- Queue模式下,为何只有未被接收的消息才能在控制台看到?能否保留已发送消息的历史?
- Pub/Sub模式下,为何无论消息是否被消费,控制台都无显示?
@JmsListener注解是否属于有效订阅?将发布者和订阅者放在同一项目是否可行?
问题解答
1. Queue模式相关问题
- 原因:Queue是点对点模型,消息被消费者接收并确认后,Broker会立即从队列中移除该消息,所以只有未被消费的消息会留存,能在控制台查到。
- 保留消息历史:可以通过ActiveMQ Artemis的配置实现。在Broker的核心配置文件(如
broker.xml)中,开启队列的持久化存储,同时可设置消息过期时间、启用消息审计日志,让已消费的消息也能被记录追踪。
2. Pub/Sub模式无消息显示的原因
- 默认订阅特性:Pub/Sub默认是非持久化订阅,只有订阅者在线时发送的消息才会被接收;如果发送消息时没有订阅者,Broker会直接丢弃消息;消息被消费后也会立即移除,所以控制台看不到留存的消息。
- 目的地拼写问题:注意到Sender发送的目的地是
test-destination,但Receiver监听的是test-destinaton(少了一个字母i),这会导致订阅与发送的目的地不匹配,消息无法被正确接收。如果实际测试中消息能正常接收,可能是已经修正了这个拼写错误,但这是需要重点排查的点。
3. @JmsListener与同项目部署问题
@JmsListener是有效订阅方式:Spring Boot中,必须在主类添加@EnableJms注解,@JmsListener才能生效,自动注册为订阅者/消费者(你当前未添加该注解,这会导致监听器无法正常工作)。- 同项目部署可行:发布者和订阅者放在同一项目完全没问题,开发测试场景中很常用,启动项目后调用Sender发送消息,同项目的Receiver就能直接消费。但生产环境通常会拆分生产者和消费者独立部署,以实现解耦和独立扩展。
内容的提问来源于stack exchange,提问作者CoderJammer
相关产品推荐
相关产品推荐

