如何在RabbitMQ中实现循环主题交换

时间:2017-07-14 06:04:42

标签: rabbitmq apache-kafka message-queue amazon-kinesis

我知道在主题交换中实现循环行为可能很棘手或不可能,所以我的问题实际上是我可以从RabbitMQ中做出什么,或者转向支持它的其他消息队列。

以下是我的申请要求的详细说明:

  1. 将有一个制作人,我们称之为P
  2. 有(可能)成千上万的消费者,我们称之为Cn
  3. 每个消费者都可以“订阅”一个或多个主题交换,多个消费者可以订阅相同的主题
  4. 发布到主题中的每条消息都应该只由一个消费者使用
  5. 用例#1

    假设:

    主题

    • foo.bar
    • foo.baz

    消费者

    • 消费者C1订阅了主题#
    • 消费者C2订阅了主题foo.*
    • 消费者C3订阅了主题*.bar

    制作人P发布以下消息:

    1. 发布foo.quxC1C2可能会使用此消息但只有一个会收到此消息
    2. 发布foo.barC1C2C3可能会使用此消息但只有一个会收到此消息
    3. 注意的 不幸的是,我不能为每个“主题”设置单独的队列,因此使用Direct Exchange不起作用,因为主题组合的数量可能很大(数万)

      据我所知,RabbitMQ没有开箱即用的解决方案。有没有人知道一个解决方法,或者有另一个支持这个的消息队列解决方案,例如。 Kafka,Kinesis等。

      谢谢

1 个答案:

答案 0 :(得分:1)

交换的角色(路由消息)和队列(似乎是为等待处理的消息提供保留位置)似乎存在混淆。将消息汇集到一个或多个队列中是交换的工作,而将消息从队列汇集到多个消费者是队列的工作。循环赛只会为后者发挥作用。

从根本上说,topic交换通过复制消息来运行,每个消息对应于与消息一起发布的主题的每个队列。因此,任何对循环行为的期望都是错误的,因为它违背了topic交换的定义。

所有这一切都是为了确定,根据定义,问题中提出的情景没有意义。 意味着所需的行为是不可能的,但术语和拓扑可能需要一些明确的调整。

让我们退后一步,查看一条消息所描述的生命周期:它只由一个生产者生产,并由许多消费者中的一个消费者生产。通常,这是直接交换所解决的情况。这方面的复杂因素是您的消费者对他们将使用哪种类型的消息有选择性(或者换句话说,您的生产者对其产生的消息类型不一致)。

通常在面向消息的处理中,单个消息类型对应于单个消费者类型。因此,每种不同类型的消息都将获得其自己的相应队列。但是,根据此问题中给出的描述,单个消息类型可能对应于多个不同的消费者类型。我遇到的一个问题是以下声明:

  

不幸的是,我不能为每个"主题提供单独的队列"

从表面上看,这句话毫无意义,因为它真正说的是你有任意多个(实际上是未知数量的)消息类型;如果是这种情况,那么您将如何编写代码来处理它们?

因此,稍微忽略该语句,我们可以开始使用RabbitMQ的两种可能性:

  1. 使用直接交换并使用消息类型作为路由密钥发布消息。然后,让您的各种消费者只订阅他们可以处理的消息类型。 这是最常见的邮件处理模式。

  2. 使用主题交换,然后提出某种外部重复数据删除逻辑(可能是memcached),其中根据消息进行检查并在另一个消费者开始处理消息时将其丢弃。 / p>

  3. 现在,这些都没有明确规定循环要求。由于没有解释为什么或如何重要,因此可以忽略它。如果没有,则需要进一步定义问题空间。