在同一个 SpringBoot 应用程序的 MQTT 接收器中未收到使用 JMS 生产者发送的消息

问题描述

我刚开始使用 ActiveMQ Artemis,并在我的机器上安装了 Artemis 2.17.0。创建了 SpringBoot 测试应用程序,其中 JMS 和 MQTT 发布者和接收者都存在。还创建了小型 RestController,以便我可以使用 JMS 和 MQTT 生产者发送消息。接收器非常简单,只需向控制台创建一条日志消息即可。现在,当我使用 MQTT 生成器创建消息时,JMS 和 MQTT 接收器都会获取消息并将其记录到控制台。但是当我使用 JMS 生产者发送消息时,该消息仅在 JMS 接收器中接收,控制台中没有 MQTT 消息。试了几次。实现没问题,我认为 MQTT 生产者示例工作正常。以这种方式在 Artemis 中的协议之间路由消息是否有任何限制?或者会是什么问题?

解决方法

Apache ActiveMQ Artemis 具有灵活的 addressing model,支持点对点和发布订阅模式。 默认情况下,Spring Boot 创建一个 JmsTemplate 配置为点对点传输,而 MQTT 使用发布-订阅模式,因此 JMS 和 MQTT 接收器使用不同的消息传递模式,这会导致您的问题。

通过 Boot 的 spring.jms.pub-sub-domain=true 为发布-订阅模式集 application.properties 配置 JmsTemplate 或将 JmsTemplate pubSubDomain 设置为 true,即:

jmsTemplate.setPubSubDomain(true);

通过 Boot 的 spring.jms.pub-sub-domain=true 为发布-订阅模式集 application.properties 配置 JmsListener 或将 JmsListenerContainerFactory pubSubDomain 设置为 true,即:

@Bean
public JmsListenerContainerFactory<?> topicConnectionFactory(ConnectionFactory connectionFactory,DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory,connectionFactory);
    factory.setPubSubDomain(true);
    return factory;
}

@JmsListener(destination = "${prices.mqtt.east}",containerFactory = "topicConnectionFactory")
public void receiveFromTopic(String message) {
    ...
}