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

时间:2012-01-02 23:22:29

标签: java jms messaging activemq

我有一个将消息推送到主题的发布者。我有多个订阅者,一旦他们使用来自主题的消息,就会执行不同的任务。 现在,我希望我的系统可以扩展到在不同主机/同一主机上运行的同一进程的多个实例。例如我想在不同的主机上运行我的应用程序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”时,没有任何反应。

感谢

2 个答案:

答案 0 :(得分:5)

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

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

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

  3. 没有明确记录的要求不直观。要使虚拟主题工作,您需要

    • 在主题名称中使用VirtualTopic.,例如VirtualTopic.Orders(可以配置此前缀)
    • 在您的队列名称中使用Consumer.。与Consumer.ApplicationA.VirtualTopic.Orders一样,其中 ApplicationA 实际上是您的客户ID
    • 在上面的队列中使用常规订阅者而不是持久订阅者。
  4. 示例:

    string activeMqConsumerTopic = "Consumer.AmqTestConsumer.VirtualTopic.Orders";
    
    IQueue queue = SessionUtil.GetQueue(session, activeMqConsumerTopic);
    
    IMessageConsumer consumer = session.CreateConsumer(queue);
    

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

    希望这有帮助。

答案 1 :(得分:1)

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

虚拟主题有助于实现以下目标: 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