RabbitMQ,docker,单队列,多个消费者

时间:2017-07-07 10:01:49

标签: java spring docker rabbitmq

我们在系统中使用Docker,Spring和RabbitMq。我是AMQP的新手,我试图弄清楚交换,队列,绑定和连接如何在我们的系统中运行。 我们有多个dockerized应用程序。

简而言之,当应用程序启动时,它们每个都开始收听同一个队列,而我并不了解它们如何能够收到相同的消息。 stackoverflow中有一些类似的问题给我的印象是我们当前的系统可能存在缺陷。

更详细:

当docker容器启动时,不同容器中的多个应用程序使用RabbitAdmin

declare the same exchange: rabbitAdmin.declareExchange(exchange)
declare the same queue: rabbitAdmin.declareQueue(queue)
bind those together: rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(exhange).with("theSameKey");

他们这样做是因为他们想听同样的消息。 据我所知,只有一个dockerized程序设法创建交换和队列,其余的尝试但没有效果。

之后,这些应用程序中的每一个都为队列创建并启动SimpleMessageContainer:

simpleMessageContainer.setMessageListener(messageListener)
simpleMessageContainer.addQueueNames(queue.getName())
simpleMessageContainer.start()

使用rabbitmqctl和rabbitmq的web界面,我可以看到单个队列在不同的通道上有多个消费者,对应不同的docker容器。

不是因为messageListener驻留在应用程序中,但是当调用addQueueNames时,RabbitMq会在代理处为队列创建一个Consumer,然后这个Consumer通过连接将消息转发到应用程序本地messageListener?

由于不同docker容器中的多个应用程序都是这样做的,因此同一个队列中有几个使用者,就像我用rabbitmqctl看到的那样。

我不明白的是,RabbitMq不会以循环方式将最终在队列中的消息传递给频道/消费者,因此只有一个dockerized应用程序会接收它吗? 主要是直接和主题​​类型,没有扇出交换。 如果所有dockerized应用程序都希望收到相同的消息,那么它们是否应该为具有自己的队列名称但具有相同路由密钥的相同exhance创建自己的队列?

我无法看到当前实现如何正常运行。

2 个答案:

答案 0 :(得分:0)

  

简而言之,当应用程序启动时,他们每个人都开始收听同一个队列,而我并不了解他们都希望收到相同的消息< / strong>即可。

他们永远不会收到相同的消息。只有一个人会选择一条消息。

要执行您的要求 - 所有人都收到相同的消息 - 它必须是主题,而不是队列

BTW:没有关于Docker或容器的具体内容,多个消费者可以通过多种方式运行。作为经典集群环境中的示例。

答案 1 :(得分:0)

  • 每个容器(实际上在里面运行的应用程序)都尝试声明交换和队列。声明后,所有其他声明命令都不起作用(即使参数不同)。
  

RabbitMq不会以循环方式将最终在队列中的消息传递给频道/消费者。

这是正确的。虽然您可以使用prefetch_count和消息ack来影响它。

  

如果所有dockerized应用程序都希望收到相同的消息,那么它们是否应该为具有自己队列名但具有相同路由密钥的同一交换创建一个自己的队列?

是的,这是唯一的方法,因为根据AMQP协议消息在消费者之间进行负载平衡。因此,如果要由所有容器(消费者)处理相同的消息,则每个容器应该具有连接到同一交换的不同队列(direct路由将执行)。

消费者是否正在使用泊坞窗或其他方式运行。