当前位置: 首页 > 知识库问答 >
问题:

使用ActiveMQ创建持久主题和订阅者spring boot jms

夏景胜
2023-03-14

我需要为ActiveMQ创建一个主题和一个持久订阅者,我的问题是我不知道在哪里指定它。我可以创建主题并使用消息,但是当我关闭订阅者然后继续发送消息并再次打开订阅者时,它不会读取它们。

这是我目前掌握的情况:

发送消息:

    JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
    jmsTemplate.setPubSubDomain(true);
    jmsTemplate.setDeliveryMode(DeliveryMode.PERSISTENT);
    jmsTemplate.setDeliveryPersistent(true);
    jmsTemplate.convertAndSend("venta.topic",venta);

接收消息:

@JmsListener(destination = "venta.topic",id = "comercial",subscription = "venta.topic")
public void receiveMessage(Venta venta) {
    logger.log(Level.INFO, "RECEIVED : {0}",venta);      
    repository.save(venta);
}

我已经阅读了这篇文章,我明白我需要创建持久订阅者。

我也读过spring文档

我认为它与默认Jms通知器容器工厂(我没有实现,我使用的是默认配置)有关,文档显示:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    return factory;
}

但是我似乎找不到在哪里创建持久会话。我的生产者和我的订户都连接到一个独立的activemq二进制文件。

我希望你能帮助我,提前谢谢。

共有3个答案

尉迟边浩
2023-03-14

很难确定,但这个问题的一个常见原因是忘记在ConnectionFactoryBean上配置唯一的clientId。它必须是唯一的,并且是经纪人区分每个客户的方式。

赫连俊雄
2023-03-14

DefaultJmsListenerContainerFactory应具有唯一的clientId和持久的sub.true集,如下代码所示:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    factory.setClientID("brokerClientId");
    factory.setSubscriptionDurable(true);
    return factory;
}
乌翰学
2023-03-14

正如前面的答案所指出的,有必要在工厂设置客户端ID和持久订阅:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory());
    factory.setDestinationResolver(destinationResolver());
    factory.setConcurrency("3-10");
    factory.setClientID("brokerClientId");
    factory.setSubscriptionDurable(true);
    return factory;
}

但仅凭这一点并不能将客户端注册为持久订阅者,这是因为 JMSListener 需要指定的容器工厂,否则它只会采用默认值:

@JmsListener(
destination = "venta.topic",
id = "comercial",
subscription = "venta.topic",
//this was also needed with the same name as the bean above
containerFactory = "jmsListenerContainerFactory" 
)
public void receiveMessage(Venta venta) {
            logger.log(Level.INFO, "RECEIVED : {0}",venta);      
            repository.save(venta);
}

值得一提的是,这篇文章让我意识到了自己的错误。

我希望这能帮到别人

 类似资料:
  • 在我们的业务需求中,我们需要将更新传输到分布在全国各地的数千个客户端。问题是,许多这些客户端使用3G网络连接到我们,因此,发生了许多连接/断开连接...我们需要提供的更新是诸如“企业A不能再兑现”或“企业B能够再次兑现”之类的东西,我们正在考虑使用ActiveMQ持久主题来提供这些更新。我的理解是,一旦客户端连接到持久主题,即使他断开连接,每当他回来时,他都会在脱机时收到发送到该主题的消息。最大的

  • 我想配置一个持久主题,但我想配置Apache ActiveMQ Artemis将为该主题的非活动持久订阅服务器保留消息的时间。 例如,类似“为非活动的持久订阅服务器保存持久消息长达30秒”的内容。如果订阅服务器在30秒内没有变为活动状态,则当订阅服务器变为活动状态时,消息将不再可用。

  • 我们有一个ActiveMQ代理,它使用JMS、AMQP和MQTT从非常不同的客户端连接到。出于某种原因,我们还没有弄清楚一组特定的MQTT客户端经常(不总是)持久订阅。这是一个测试环境,客户端经常被添加和删除,后者有时通过拔掉插头或重新启动嵌入式设备,因此它们无法正确取消订阅。效果(IIUC)是代理为可能再也见不到的设备堆积“离线持久订阅”(我可以在超文本传输协议下看到这些),永远保留关于这些主题

  • 我正在尝试编写一个基本的 ActiveMQ 客户端来侦听一个主题。我正在使用Spring启动活动MQ。我有一个基于各种教程构建的实现,它使用默认Jms列表容器工厂,但是我在使其正常工作时遇到了一些问题。 一切都很好,直到我尝试获得一个持久的订阅。当我这样做时,我发现在容器工厂中设置了客户机id,我得到了一个关于如何在共享连接上设置客户机id的错误。 <code>原因:共享连接的代理不支持setCl

  • 我在这里对如何正确使用ActiveMQ有点困惑。 我想做的是 系统A向虚拟主题发送消息。然后系统B和C都使用来自同一虚拟主题的消息。系统B或C可能会脱机。所以当它们重新联机时,我需要它们接收脱机期间产生的所有消息。 到目前为止我所尝试的 我读过关于持久订阅者(http://activemq.apache.org/how-do-durable-queues-and-topics-work.html

  • 参考Link,我使用JMS ActiveMQ SpringBoot创建了持久订阅者。我还使用UUID.randomUUID()生成了惟一的客户机ID。toString()。然而,在启动订户(接收器)时,应用程序抛出以下警告消息 请帮我删除上述警告信息。 Receiver.java 学生.java SendMessageApplication.java 主题发送消息.java