2016-08-14 22 views
2

相当新的RabbitMQ,我试图看看我能否实现我所需要的。RabbitMQ - 单个并发工作者每个路由密钥

我正在寻找工作队列模式,但有一个警告。我想只有一个工作者同时运行每个路由键。

澄清一个例子:

如果我的顺序发送具有路由键下面的消息:aabc,我想只有3个工人同时运行。当收到第一个a消息时,工作人员将其拿起并处理。

当收到下一个a消息并且之前的a消息仍然处理(未确认)时,新的a消息应在队列中等待。当接收到bc消息时,他们每个都会得到一个处理它们的工作人员。当第一个a消息被确认时,任何工人都可以拿起下一个a消息。

另一个澄清:

会以自然的方式使用RabbitMQ的(不站在我这一边写任何程序代码来处理的锁定和东西...)

编辑模式是可能的。所有员工都可以并且应该处理所有消息,并且我不希望为每个员工设置一个队列,因为我想分担他们之间的负载,而发布者不知道哪个工作人员应该处理消息。但我确实希望确保没有2名工人正在同时处理共享相同密钥的消息。

例如,如果我有一个Publisher发布带有userId字段的邮件,我想确保没有2个工作人员同时处理具有相同userId的邮件。

编辑2

扩大上userId例子。假设我有一个发布者和3个工人。发布者发布如下消息:{ userId: 1, text: 'Hello' },其变化范围为userId s。我的3名工人都对这条消息做了同样的事情,所以我可以让他们中的任何一位处理消息。但是我试图实现的是只有一个工作人员处理来自某个用户的消息时间。如果工作人员收到一条消息,并且正在处理该消息,并且收到另一条消息userId 1,我想确保没有其他工作人员收到该消息。但其他消息与不同的userId s应该由其他可用的工作人员处理。

userId s是事先不知道的,发布者不知道有多少员工是他们的具体情况,他只是想要安排消息进行处理。

回答

1

你的问题不能用路由密钥来实现,而是通过一些设置构建到队列中。

如果您为a消息定义了“queue_a”,为b消息定义了“queue_b”,那么您可以让尽可能多的消费者连接到它。

RabbitMQ只会将给定的消息传递给给定队列的单个消费者。

它与单个队列上的多个使用者一起工作的方式是基本的循环调度消息。也就是说,第一条消息将被传递给其中一个消费者,并且下一条消息(假设第一消费者仍然很忙)将被传递给下一个消费者。

因此,这应该满足将消息传递给队列中的任何给定消费者的需要。

为了确保您的邮件能够获得任何消费者的同等机会(并且并非全部都是全部交付给同一个消费者),还需要执行其他一些设置。

首先,请务必将消息使用者no ack设置为false(有时称为“自动确认”)。这会强制您从ack来自代码的消息。

最后定下了居民消费的“消费预取”上限为1

有了这种设置组合,单次消费将检索一条消息,并开始做这个工作。当该消费者正在工作时,队列中等待的任何消息将被传递给其他消费者(如果有的话)。如果没有可用的消息,则消息将在队列中等待,直到消费者可用。

有了这个,你应该能够在给定的队列上实现你想要的行为。

...

请记住,这只适用于队列,但。路由密钥不能通过这种方式进行管理。来自交换机的所有匹配的路由密钥都会导致将消息的副本发送到目标队列。

+0

以我的观点来看,这个计算器是正确的。但是,即使是排队的人也不会,因为问题是“任何工人都可以拿起下一个信息”,这是不可能的。在这种情况下,每个队列只有一个工作人员和一个路由密钥。所以每次同一个工作人员拿起下一条消息。 – slowjack2k

+0

谢谢,Derick,但@ slowjack2k对我的意思是正确的。我给工人的所有信息都是一样的,我不在乎(也不想关心)哪个工作人员收到信息。我只想确保只有一个工作人员根据某个键(我为每条消息生成的)输入一些消息。 –

+0

@NetanelG这两个陈述并不一致'我的所有工作人员的消息都是相同的'和'基于某个键的消息(我为每个消息生成的)'Aslo Derick的答案对于你问过的问题是正确的你问过它,但基于这个评论,我认为你应该编辑它。 – cantSleepNow

相关问题