RabbitMQ:如何组合任务队列和扇出/路由/主题模型?

RabbitMQ:如何组合任务队列和扇出/路由/主题模型?,rabbitmq,Rabbitmq,我有一个由一个生产者和多个消费者组成的环境。 生产者创建两种类型的消息: 需要由一个使用者处理的消息只有任何使用者才会处理。 需要所有使用者处理的消息。 如何实现这一点? 对于消息类型1,工作队列是合适的模型。 对于消息类型2,扇出/直接/路由/主题是合适的。 但是我如何组合它们呢?直接路由和扇出路由是RabbitMQ交换的属性。所有RabbitMQ消息都将发布到exchange,而不是直接发布到队列。当您创建和使用队列时,没有显式创建exchange,实际上您使用的是预先声明的默认exchan

我有一个由一个生产者和多个消费者组成的环境。 生产者创建两种类型的消息:

需要由一个使用者处理的消息只有任何使用者才会处理。 需要所有使用者处理的消息。 如何实现这一点? 对于消息类型1,工作队列是合适的模型。 对于消息类型2,扇出/直接/路由/主题是合适的。
但是我如何组合它们呢?

直接路由和扇出路由是RabbitMQ交换的属性。所有RabbitMQ消息都将发布到exchange,而不是直接发布到队列。当您创建和使用队列时,没有显式创建exchange,实际上您使用的是预先声明的默认exchange

您可以在单个RabbitMQ代理上创建多个交换,并且可以将单个队列绑定到多个交换。如果希望工作者对这两种消息类型使用相同的队列,可以为消息类型1创建直接交换,为消息类型2创建扇出交换,并将每个队列绑定到这两个交换。否则,您可以为每种exchange类型创建单独的队列


RabbitMQ对交换和队列有很好的解释,RabbitMQ页面上的教程3向您展示了如何创建和绑定交换。

RabbitMQ非常灵活,您可以有许多不同的交换和队列设计解决方案来满足您的需求

但是,首先,我们需要了解队列和消费者之间的关系和基本规则:

如果您希望一个消息类型仅由所有使用者中的一个使用者使用,正如您所说,您需要一个工作队列,那么所有使用者都应该订阅它。 如果希望每个使用者使用消息类型,则需要为每个使用者设置队列,并且每个使用者仅订阅其自己的队列。 根据上述理解,当队列数量明确时。剩下的就是如何将消息路由到这些队列。将有许多解决办法。下面只是一些例子

一个可行的解决方案是创建两个交换,每种消息类型一个

| message type | exchange name | exchange type | bound queues      |
|------------------------------------------------------------------|
| type_1       | exchange1     | fanout        | shared_queue      |
| type_2       | exchange2     | fanout        | queue1,queue2,... |
另一个可行的解决方案是,如果只想使用一个exchange将两种邮件类型发布到,请使用“直接”exchange类型:

| routing_key | binding_key | bound queues      |
|-----------------------------------------------|
| type_1      | type_1      | shared_queue      |
| type_2      | type_2      | queue1,queue2,... |
一个exchange可以使用相同的绑定密钥将多个队列绑定到它。因此,当使用发布路由密钥类型_1发布消息类型1时,只有共享_队列将接收该消息;使用发布路由密钥-type_2发布消息类型2时,所有队列1、队列2、,。。。将收到该消息

如果您有更多的消息类型,并且不想使用相同的路由密钥,那么为每个消息使用不同的绑定密钥对于实际情况可能并不理想。如果是这样,您可能希望改用主题交换类型:

| routing_key | binding_key | bound queues      |
|-----------------------------------------------|
| type_1.1    | type_1.*    | shared_queue      |
| type_2.2    | type_2.*    | queue1,queue2,... |

谢谢你的详细回答。如果我理解正确,您建议单个消费者可以订阅多个队列?从Rabbit的教程中,我得到的印象是消费者可以订阅单个队列如果消费者是指消费者应用程序,作为应用程序,那么是的,它当然可以订阅任意多的队列。在您的应用程序中,您可以有多个连接或共享一个连接中的多个通道,每个通道订阅不同的队列。谢谢。我会试试你的建议。