【发布时间】:2016-07-06 21:02:03
【问题描述】:
我有一个由一个生产者和多个消费者组成的环境。
生产者创建两种类型的消息:
- 只需要一个消费者处理的消息(任何消费者都可以)。
- 需要所有消费者处理的消息。
如何实现?
对于消息类型 1,工作队列是合适的模型。
对于消息类型 2,扇出/直接/路由/主题是合适的。
但是我该如何组合它们呢?
【问题讨论】:
标签: rabbitmq
我有一个由一个生产者和多个消费者组成的环境。
生产者创建两种类型的消息:
如何实现?
对于消息类型 1,工作队列是合适的模型。
对于消息类型 2,扇出/直接/路由/主题是合适的。
但是我该如何组合它们呢?
【问题讨论】:
标签: rabbitmq
RabbitMQ 非常灵活,您可以有许多不同的交换和队列设计解决方案来满足您的要求。
但是,首先,我们需要了解队列和消费者之间的关系和基本规则:
当基于以上理解明确队列数量时。剩下的事情是如何将您的消息路由到这些队列。会有很多解决方案。以下只是一些示例。
一个可行的解决方案是创建两个交换,每个消息类型一个。
| message type | exchange name | exchange type | bound queues |
|------------------------------------------------------------------|
| type_1 | exchange1 | fanout | shared_queue |
| type_2 | exchange2 | fanout | queue1,queue2,... |
另一个可行的解决方案是,如果您只想有一个交换来发布两种消息类型,请使用“直接”交换类型:
| routing_key | binding_key | bound queues |
|-----------------------------------------------|
| type_1 | type_1 | shared_queue |
| type_2 | type_2 | queue1,queue2,... |
一个交换可以有多个使用相同绑定键绑定到它的队列。因此,当使用发布路由键 - "type_1" 发布消息类型 1 时,只有 shared_queue 会收到消息;使用发布路由键“type_2”发布消息类型 2 时,所有 queue1,queue2,... 都会收到消息。
如果您有更多消息类型并且您不想使用相同的路由键,则对每条消息使用不同的绑定键可能不适合实际情况。如果是这样,您可能想改用“主题”交换类型:
| routing_key | binding_key | bound queues |
|-----------------------------------------------|
| type_1.1 | type_1.* | shared_queue |
| type_2.2 | type_2.* | queue1,queue2,... |
【讨论】:
直接与扇出路由是 RabbitMQ 交换的属性。所有 RabbitMQ 消息都发布到交换器,而不是直接发布到队列——当您创建和使用队列而不显式创建交换器时,您实际上是在使用预先声明的默认交换器。
您可以在单个 RabbitMQ 代理上创建多个交换,并且可以将单个队列绑定到多个交换。如果您希望工作人员对两种消息类型使用相同的队列,您可以创建一个直接交换(用于消息类型 1)和一个扇出交换(用于消息类型 2)并将每个队列绑定到两个交换。否则,您可以为每种交换类型创建单独的队列。
RabbitMQ 的AMQP concept guide 对交换和队列有很好的解释,RabbitMQ Getting Started 页面上的教程 3 向您展示了如何创建和绑定交换。
【讨论】: