繁体   English   中英

Java是否可以侦听多个RabbitMQ队列?

[英]Is it possible to have Java listen to multiple RabbitMQ queues?

更新:我认为我的解释可能太冗长,所以我想一个简单的想法来思考一下:我有多个工作节点,我想将它们用于不同的任务(这些不同的任务来自不同的任务队列)。 目前,我只知道如何让他们侦听与单一工作类型相关的单个队列,但是我希望他们侦听不同的队列,以便在出现不同的工作时,同一节点集群可以处理它们。 希望那更加清楚。


大家好,我怀疑这是可能的,但我似乎无法弄清楚该怎么做。 我浏览了Rabbitmq网站上的教程,它们确实很有帮助,并且做了我想做的,只是它没有显示如何在同一程序中侦听多个队列。

我的程序结构基本上是几个阶段。例如,阶段1收集大量数据,然后阶段2处理该数据并将其加载到数据库中,阶段3根据其他数据对其进行分析,等等。每个阶段直到上一个阶段才能开始阶段已完成,我想使用队列系统来使用多台计算机更快地完成每个阶段(因此,所有使用者在阶段1上工作,然后全部完成后,便一起在阶段2上工作,依此类推)。

我想我不能只完成每个阶段一次,因为队列可能为空,并且计算机将移至下一个队列,而且我无法知道是因为所有工作都已经完成还是因为我们没有完成而已经完成了,还没有开始工作。 因此,我认为(如果我错了,请纠正我)一种更好的方法是侦听与所有阶段相关的所有队列,并且当工作被放入phase1Queue时它就可以在其上工作,如果工作被放入phase2Queue则它可以在之后就对其进行了(我要描述的过程之外还有另一个过程,它监视每个阶段的完成时间并为下一个阶段进行设置。 希望有道理。

队列示例中的代码对消费者侦听一个队列很有帮助,但是如何使它侦听多个队列(并根据不同的队列调用不同的程序)。 如果已经有一个功能了,那就太棒了,但是我正在寻找可以用于在Java中实现此功能的逻辑(最坏的情况是我想运行5个独立的程序来监听每个队列,但是我试图找出答案如果有更好的方法,将一个应用程序与我的所有工作都包含在内,将使分发管理更加容易。

谢谢!

ps(如果有帮助),这里是适用于rabbitmq的使用者代码(但您可以看到它仅定义了一个队列):

import java.io.IOException;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;

public class Worker {

  private static final String TASK_QUEUE_NAME = "task_queue";

  public static void main(String[] argv)
                      throws java.io.IOException,
                      java.lang.InterruptedException {

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

    channel.basicQos(1);

    QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume(TASK_QUEUE_NAME, false, consumer);

    while (true) {
      QueueingConsumer.Delivery delivery = consumer.nextDelivery();
      String message = new String(delivery.getBody());

      System.out.println(" [x] Received '" + message + "'");   
      doWork(message); 
      System.out.println(" [x] Done" );

      channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
    }
  }
  //...
}

更新:根据评论,协调程序非常简单。 它只是一个从Phase1Queue监视的程序,一旦该队列为空,它就简单地启动一个进程来填充Phase2Queue等。

另一种方法是将不同的阶段分为不同的模块/服务/流程,并使所有这些模块同时运行。

每个阶段的使用者都收听不同的队列。 每个阶段负责为下一阶段的队列生成消息。

这样,您只需承担一个职责即可降低复杂性。 每个进程都从一个特定的队列中消费,并产生另一个队列。 然后,您可以根据需要扩大和/或缩小这些单独的流程。

这是我们使用的模式。 我们有一个初始作业,最终可以从中创建多达100倍的子作业。 初始作业非常小且可以快速运行,而子作业可能是长期运行的请求,我们将为一小群云实例提供服务。 然后,这些作业通过另一个队列返回其结果,然后将其结果整理并添加到数据库中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM