RabbitMQ中的主题交换与直接交换

Mun*_*Mun 48 message-queue rabbitmq rabbitmq-exchange

我们有一个应用程序将使用RabbitMQ并有几个不同的队列在层之间传递消息.

最初,我计划使用多个直接交换,每个消息类型一个,但看起来使用不同的路由键绑定与队列进行单个主题交换将实现相同的目的.

进行单次交换似乎也更容易维护,但我想知道是否有任何好处(如果有的话)以另一种方式做到这一点?

选项1,使用多个直接交换:

ExchangeA (type: direct)
-QueueA

ExchangeB (type: direct)
-QueueB

ExchangeC (type: direct)
-QueueC
Run Code Online (Sandbox Code Playgroud)

选项2,使用单一主题交换:

Exchange (type: topic)
-QueueA  (receives messages from exchange with routing key of "TypeA")
-QueueB  (receives messages from exchange with routing key of "TypeB")
-QueueC  (receives messages from exchange with routing key of "TypeC")
Run Code Online (Sandbox Code Playgroud)

Bri*_*lly 36

假设两个模型都被认为是使用一个代理运行来实现的,那么我可以看到的差别不大.

选项2似乎在现实世界中更常见,以解决这种路由问题(至少在我的轶事经验中),这正是主题交换存在要解决的挑战.

您可能遇到的唯一区别与路由速度有关.我不确定与主题交换中使用的路由密钥技术(可以包括#和等通配符*)相比,RabbitMQ中的Exchange路由(总是基于精确的字符串匹配)是否更快.我的预感是,Exchange歧视会更快,但您可以自己试验一下,或尝试联系RabbitMQ团队询问他们.

最后,如果您使用选项1结束了大量队列,那么您将拥有成比例的Exchange扩散.这听起来像一个维护头痛.如果你只有少数几个队列,那么问题不会太多.

  • 我同意.具有适当路由密钥的多个队列更容易管理.考虑到选项1的唯一优点是可以在单独的硬件上托管多个交换,从而实现垂直扩展.但是,如果您的硬件出现问题,那么您可能永远不需要采用这种方式. (2认同)
  • 我认为使用 Topic 的好处是,如果将来您需要将相同的消息发送到交换中的多个队列,那么您的选项 2 会更可取。 (2认同)

vin*_* hy 13

实际上,方法2更好,因为它使您可以灵活地将单个队列用于多个路由键.

交流主题

QueueA-- binding key = India.Karnataka.*
Run Code Online (Sandbox Code Playgroud)

您可以使用路由密钥将消息路由到主题交换,如India.Karnataka.bangalore,India.Karnataka.Mysore.

以上所有消息都发送到QueueA.

直接交流

但我不明白你为什么在方法1中创建多个直接交换.你可以有单个直接交换,并有多个队列,每个队列绑定一个唯一的密钥.

QueueA-- binding key = Key1
QueueB-- binding Key = Key2
QueueC-- binding Key = Key3
Run Code Online (Sandbox Code Playgroud)

所有key1消息都转到QueueA.Key2转到QueueB ...您仍然可以保持单个直接交换.


Abe*_*lgo 6

对于负载很小的单个小节点,差别不大.出于上述原因,大多数人选择选项二.

在设计系统时,您应该问自己将来如何扩展.

它如何扩展?
我需要它来扩展吗?我想在将来添加高可用性群集吗?我的路由会改变吗......

在大多数情况下,选项2提供了更大的灵活性.

它允许您执行诸如使用自己的队列将新使用者附加到Exchange并轻松捕获任何子集或所有消息流的操作.(这些队列可以在群集中的其他节点上,也可以镜像到n个节点,提供故障转移)典型的用例是使用第4个队列记录所有消息.

如果您的瓶颈在处理方面,您还可以进一步细分您的邮件主题并执行一些优先级,而无需更改您的发布者.示例:由专用消费者处理的ToppicA.urgent,最终处理了TopicA.log.

简短的回答是选项2,除非您有非常具体的性能要求,例如,如果您需要处理超过50k msg/s的持续速率,您可能需要考虑专用节点上的选项1,但对于正常流程选项2将更容易扩展和维护.