从ActiveMQ迁移至ActiveMQ Artemis后未收到advisory消息的问题
我们有一个基于ActiveMQ的JMS应用,通过ActiveMQ advisory messages实现核心功能(比如获取队列消费者数量)。
迁移至ActiveMQ Artemis 2.24.0后,发现完全无法接收advisory消息:
- 已按官方文档配置OpenWire协议,设置了
supportAdvisory=true和suppressInternalManagementObjects=false - 管理UI中能看到advisory队列、地址,也能确认消费者已存在
- advisory队列消息数始终为0,说明Artemis未主动发送这类消息
- 手动向advisory队列发送消息时,客户端能正常接收,证明消费者绑定逻辑正确
应用基于Spring Boot框架,核心监听代码如下:
@JmsListener(destination = "ActiveMQ.Advisory.Consumer.Topic.Application", containerFactory = "jmsFactory") public void checkIfBecomeMaster(Message message) { try { consumerCount = Integer.valueOf(message.getStringProperty("consumerCount")); // 其他业务逻辑... } catch (JMSException e) { e.printStackTrace(); } }
请问我们遗漏了哪些配置?是否需要额外插件?我们清楚有其他方式查询Artemis数据,但希望尽可能原封不动完成迁移。
针对你的问题,以下几个配置和细节需要逐一排查:
确认OpenWire连接器的参数配置
Artemis中supportAdvisory和suppressInternalManagementObjects是OpenWire协议专属参数,必须配置在OpenWire acceptor的URL参数中,而非全局broker配置。确保broker.xml中的OpenWire acceptor配置如下:<acceptor name="openwire">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=OPENWIRE;supportAdvisory=true;suppressInternalManagementObjects=false</acceptor>全局配置这两个参数不会生效,必须附加到OpenWire acceptor的连接参数里。
验证advisory地址的自动创建规则
Artemis默认自动创建advisory地址,但需确保未禁用地址/队列自动创建。检查broker.xml的address-settings,针对advisory地址添加明确配置:<address-settings> <address-setting match="ActiveMQ.Advisory.#"> <auto-create-queues>true</auto-create-queues> <auto-create-addresses>true</auto-create-addresses> <default-address-routing-type>MULTICAST</default-address-routing-type> </address-setting> <!-- 其他地址配置... --> </address-settings>由于advisory消息属于Topic类型,必须确保地址路由类型为
MULTICAST。修正JMS监听器的Topic模式配置
你订阅的ActiveMQ.Advisory.Consumer.Topic.Application是Topic类型目的地,需确保Spring Boot的JMS容器启用Pub/Sub模式:- 在
@JmsListener中显式指定目的地类型:@JmsListener(destination = "ActiveMQ.Advisory.Consumer.Topic.Application", containerFactory = "jmsFactory", destinationType = "topic") - 调整JMS容器工厂配置,开启Pub/Sub域:
@Bean public JmsListenerContainerFactory<?> jmsFactory(ConnectionFactory connectionFactory) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory); factory.setPubSubDomain(true); // 启用Topic订阅模式 return factory; }
Advisory消息不支持持久化订阅,确保监听器使用非持久化订阅模式。
- 在
匹配客户端与Artemis的版本兼容性
确保使用的activemq-client依赖版本与Artemis 2.24.0兼容,版本不匹配可能导致协议解析异常。建议使用官方推荐的兼容版本(如5.17.6):<dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-client</artifactId> <version>5.17.6</version> </dependency>检查安全权限配置
如果Artemis启用了安全插件,需确保客户端角色拥有advisory地址的消费权限。在broker.xml的security-settings中添加:<security-settings> <security-setting match="ActiveMQ.Advisory.#"> <permission type="consume" roles="your-client-role"/> <permission type="createNonDurableQueue" roles="your-client-role"/> </security-setting> </security-settings>
按上述步骤调整后,Artemis应该能正常发送advisory消息到你的客户端。
内容的提问来源于stack exchange,提问作者Jirka Novak

