2017-07-14 20 views
2

我知道在主题交换中实现循环法行为可能会非常棘手或根本无法实现,所以我的问题实际上是,如果我能从RabbitMQ中做出任何事情或者望向其他消息队列支持。如何在RabbitMQ中实现循环法主题交换

这里是我的应用需求进行详细的解释:

  1. 将有一个制片人,我们称之为P
  2. 有(可能)将是成千上万的消费者,我们姑且称之为Cn
  3. 每消费者可以“订阅”1个或多个话题交换并且多个消费者可以订阅同一主题
  4. 发布到该话题中的每个消息应该仅被一个消费者消费

使用案例#1

假设:

主题

  • foo.bar
  • foo.baz

消费者

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

生产者P公布下列信息:

  1. 发布foo.quxC1C2可以潜在地消耗该消息,但只有一个接收它
  2. 发布foo.barC1C2C3可以潜在地消耗该消息,但只有一个接收它

注意 不幸的是,我不能为每个“主题”有一个单独的队列,因此使用Direct Exchange不工作k因为主题组合的数量可能很大(数以万计)

从我读过的内容来看,RabbitMQ没有开箱即用的解决方案。有人知道解决方法,或者有另一个消息队列解决方案可以支持这一点,例如。卡夫卡,Kinesis等

谢谢

+1

虽然我理解了这个问题,并发现它的反常性非常有趣(这可以说是100%足够的问题),但我也很好奇这个用例。在我看来,话题交换旨在发布关于“主题”的消息,并让“人们”对某种类型的接收消息感兴趣。没有看到任何方式可以有效地从主题交换中“产生/消耗”,但我一定是错的。就我个人而言,除了推迟使用某些数据存储选举获胜的消费者之外,我没有看到任何其他方式。我可能是错的,我对卡夫卡和Kinesis了解不多。 – user1527491

+1

我的观点是:如果所有(或某些)消费者都被告知已发送消息,则使用话题交换。如果只有一个消费者必须以生产者/消费者的方式消费该消息,则使用直接或扇出交换。如果您需要两者,请同时使用!发布到两个交易所。但这并不能解决问题,事实上,因为你的消费者会有错误的消费者。 – user1527491

+0

顺便说一下,虽然我不是卡夫卡的专家,但我99%确信它不会帮助(甚至会更糟糕),因为它根本没有路由的概念。这是pub/sub更糟或更好的,这意味着它甚至不会帮助生产者/消费者的东西。请注意,即使RabbitMQ也不保证一次交付。 – user1527491

回答

1

似乎有交流,这是路由信息的角色糅合在一起,和队列,这是等待处理的消息提供一个固定的地方。将消息汇集到一个或多个队列是交换的工作,而将消息从队列汇集到多个消费者是队列的工作。循环赛只适用于后者。

基本上,topic交换是通过复制消息来操作的,每个消息与用消息发布的主题相匹配。因此,任何对循环赛行为的期望都是错误的,因为它违背了交易所的定义。

所有这一切只是确定,根据定义,问题中提出的方案没有意义。那而不是意味着期望的行为是不可能的,但是术语和拓扑可能需要一些明确的调整。让我们回过头来看一条消息的描述的生命周期:它由一个生产者生产,并由许多消费者之一消费。通常,这是直接交换所解决的情况。其中一个复杂的因素是,你的消费者对他们将消费什么类型的消息进行选择(或者换句话说,你的生产者对它产生的消息类型不一致)。

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

可惜我不能有一个单独的队列,每个“主题”

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

所以,忽视了一下这句话,我们都导致了与RabbitMQ的两种可能性的开箱:

  1. 使用直接交换和发布使用消息的输入消息的路由键。然后,让您的各种消费者只订阅他们可以处理的消息类型。 这是最常见的消息处理模式。

  2. 使用主题交换,并提供某种外部重复数据删除逻辑(可能是memcached),其中检查消息并将其丢弃,如果其他消费者已开始处理它。

现在,它们都没有明确处理循环法要求。既然没有解释为什么这个问题很重要,那么可以忽略它。如果不是,则需要进一步定义问题空间。

+0

的确,我寻求使用RabbitMQ的方式并不是它所设计的。然而,因为没有工具可以提供这些(至少从我所知道的),我试图弯曲消息代理的原则来涵盖我的用例。 关于_很遗憾,我不能为每个“topic”设置一个单独的队列_:并不是说消息是不同的,只会有一种消息类型,但是针对不同的消费者群体,其中只有一个消费者被随机挑选来处理它。 –

+0

那么,有工具,但没有*一个工具* - 但是,当那里有?如果所有事情都做到了你需要的东西,那么对程序员的需求会非常低。 :) – theMayer

+0

根据您的评论的后半部分,听起来您会为每个消费者组创建一个队列,然后设置您的消费者从适当的队列中拉出。这是RabbitMQ中的默认功能。 – theMayer