如何使用虚拟目的地创建多个 activemq 主题订阅者实例?

Posted

技术标签:

【中文标题】如何使用虚拟目的地创建多个 activemq 主题订阅者实例?【英文标题】:how to create multiple instances of activemq topic subscribers using virtual destinations? 【发布时间】:2012-02-01 03:26:07 【问题描述】:

我有一个将消息推送到主题的发布者。我有多个订阅者,一旦他们使用来自主题的消息,每个订阅者都会执行不同的任务。 现在我希望我的系统能够扩展到在不同主机/同一主机上运行的同一进程的多个实例。例如我想在不同的主机上运行我的应用程序 A 的多个副本,这样如果 A 的一个实例很慢,那么其他实例可以拉入后续消息并取得进展.. 我发现使用虚拟目的地可以做到这一点。我按照这里的步骤 - http://activemq.apache.org/virtual-destinations.html

但是我如何设置多个订阅者到具有相同客户端 ID 的同一主题?当我尝试这样做时,我得到了错误。当我尝试其他方式时,它不起作用。有人可以帮忙吗?

通常,我通过执行以下步骤来启动订阅者 -

        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, ActiveMQConnection.DEFAULT_BROKER_URL;);
        activeMQConnection = connectionFactory.createConnection();

        activeMQConnection.setClientID("subscriber1");
        activeMQConnection.setExceptionListener(exceptionListener);
        activeMQSession = activeMQConnection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
        activeMQTopic = activeMQSession.createTopic("myTopic");            
        activeConsumer = activeMQSession.createDurableSubscriber(activeMQTopic, "myTopic");            
        activeConsumer.setMessageListener(messageListener);
        activeMQConnection.start();

当我尝试创建第二个订阅者并将主题名称传递为“VirtualTopic.myTopic”时,没有任何反应。

谢谢

【问题讨论】:

@vinod 你提到了这些 [链接] (activemq.apache.org/virtual-destinations.html)。我在那个链接中看到了 xml 代码。在哪里可以找到那个 xml 文件。 【参考方案1】:

虚拟主题功能非常简单,一旦你理解它就非常强大。

    使用虚拟主题时 - 不需要持久的消费者。那是因为对于每个客户端,您都会创建一个常规队列的实例。如果您有 5 个客户端(应用程序 A、B、C、D、E),每次将消息发送到虚拟主题时,您将创建 5 个队列并使用消息副本填充。

    实际上这是持久消费者的一个限制 - 每个 clientId 只允许一个连接。作为常规队列,您可以创建任意数量的消费者,并且队列将保证只有 1 个消费者会收到 1 条消息。因此,如果您的应用程序 A 需要 1 分钟来处理一条消息,您可以创建 5 个它的实例来侦听同一个队列。当您在 1 秒内发布 5 条消息时,您的每个应用程序都会收到自己的消息进行处理。

    没有不直观的需求文档。要使虚拟主题发挥作用,您需要

    在主题名称中使用VirtualTopic.,例如VirtualTopic.Orders(此前缀可配置) 在您的队列名称中使用Consumer.。就像Consumer.ApplicationA.VirtualTopic.Orders 一样,ApplicationA 实际上是您的客户端 ID 对上述队列使用常规订阅者而非持久订阅者。

例子:

string activeMqConsumerTopic = "Consumer.AmqTestConsumer.VirtualTopic.Orders";

IQueue queue = SessionUtil.GetQueue(session, activeMqConsumerTopic);

IMessageConsumer consumer = session.CreateConsumer(queue);

每当订阅消费者的第一个实例时,就会自动创建队列。从那一刻起,所有发送到主题的消息都被复制/复制到所有关联的队列中。

希望这会有所帮助。

【讨论】:

【参考方案2】:

虚拟主题是您的答案。但是,您必须为所有虚拟主题队列定义命名标准。答案如下:

虚拟主题有助于以下预期: 1.消息的负载均衡 2. 订阅者的快速故障转移 3. 为不同的生产者和消费者重复使用相同的连接工厂。 (持久订阅者需要唯一的 JMS 客户端 ID,并且不能为任何其他生产者或消费者重复使用)

这是执行此操作的方法,下面的示例创建前缀 VTCON.*。因此,每个带有此前缀和最后的主题名称的队列都会消费该消息。

<virtualDestinations> <virtualTopic name="TEST.TP01" prefix="VTCON.*." selectorAware="false"/> </virtualDestinations>

http://workingwithqueues.blogspot.com/2012/05/activemq-virtual-topics-or-virtual.html

【讨论】:

以上是关于如何使用虚拟目的地创建多个 activemq 主题订阅者实例?的主要内容,如果未能解决你的问题,请参考以下文章

Activemq 中一个主题的多个侦听器如何工作?

centos 安装activeMq

使用Java编写ActiveMQ的队列模式和主题模式

Spring Integration JMS 创建 ActiveMQ 队列而不是主题

spring-消息

Spring-integration / ActiveMQ 在单个线程中订阅多个目的地