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

如何修复ActiveMQ持久订阅引发“持久消费者已在使用”错误

逑和蔼
2023-03-14

我正在尝试编写一个基本的 ActiveMQ 客户端来侦听一个主题。我正在使用Spring启动活动MQ。我有一个基于各种教程构建的实现,它使用默认Jms列表容器工厂,但是我在使其正常工作时遇到了一些问题。

@Configuration
@EnableJms
public class JmsConfig {
    @Bean
    public DefaultJmsListenerContainerFactory jmsContainerFactory(ConnectionFactory connectionFactory,
                                                                  DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConcurrency("3-10");
        factory.setConnectionFactory(connectionFactory);

        configurer.configure(factory, connectionFactory);

       factory.setSubscriptionDurable(true);
       factory.setClientId("someUniqueClientId");

       return factory;
   }
}

@JmsListener(destination="someTopic", containerFactory="jmsContainerFactory", subscription="someUniqueSubscription")
public void onMessage(String msg) {
    ...
}

一切都很好,直到我尝试获得一个持久的订阅。当我这样做时,我发现在容器工厂中设置了客户机id,我得到了一个关于如何在共享连接上设置客户机id的错误。

<code>原因:共享连接的代理不支持setClientID调用。改为在SingleConnectionFactory上设置“clientId”属性。

当我将代码更改为在连接工厂上设置客户端id时(它是一个封装ActiveMQConnectionFactory的CachingConnectionFactory),服务成功启动,读取两条消息,然后开始一致输出此错误:

< code >为目标“someTopic”设置JMS消息侦听器调用程序失败-正在尝试恢复。原因:持久使用者正用于客户端:someUniqueClientId和订阅名称:somuniquesubscription

我继续收到消息,但也有错误混杂在日志中。这似乎可能是一个问题,但我真的不清楚如何解决它。

我确实有一个天真的实现,没有任何Spring代码,直接使用ActiveMQConnectionFactory,似乎很乐意使用持久消费者(但它有自己不同的问题)。无论如何,我不认为另一方面缺乏对持久连接的支持。

我希望在这方面有更多经验的人能帮我弄清楚这个错误是不是我可以忽略的,或者我需要做些什么来解决它。

谢谢

共有1个答案

李敏学
2023-03-14

JMS 1.1(因为您正在使用ActiveMQ 5.x,所以您正在使用它)不支持共享持久订阅。因此,当您使用< code > set concurrency(" 3-10 ")并且Spring试图创建

  1. 使用<code>setConcurrency(“1”)
  2. 切换到支持JMS 2.0的ActiveMQ Artemis,并调用setSubscriptionShared(true)
 类似资料:
  • 我想配置一个持久主题,但我想配置Apache ActiveMQ Artemis将为该主题的非活动持久订阅服务器保留消息的时间。 例如,类似“为非活动的持久订阅服务器保存持久消息长达30秒”的内容。如果订阅服务器在30秒内没有变为活动状态,则当订阅服务器变为活动状态时,消息将不再可用。

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

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

  • 我需要为ActiveMQ创建一个主题和一个持久订阅者,我的问题是我不知道在哪里指定它。我可以创建主题并使用消息,但是当我关闭订阅者然后继续发送消息并再次打开订阅者时,它不会读取它们。 这是我目前掌握的情况: 发送消息: 接收消息: 我已经阅读了这篇文章,我明白我需要创建持久订阅者。 我也读过spring文档 我认为它与(我没有实现,我使用的是默认配置)有关,文档显示: 但是我似乎找不到在哪里创建持

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

  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我