RabbitMQ:从队列为多个使用者分发固定消息

时间:2019-03-09 00:13:42

标签: rabbitmq spring-amqp

是否有一种方法可以限制RabbitMQ队列仅将固定数量的消息从Queue分发到使用者?

我有2个队列Q1和Q2以及10个使用方。每个使用方都可以处理来自Q1和Q2的消息。在任何给定时间,只有2个使用方可以处理来自Q2的消息。所有10个使用方都可以同时处理来自Q1的消息。

RabbitMQ中是否可以指定任何配置,因此RabbitMQ仅将来自第2季度的2条消息推送到任何免费使用者,并在确认它们后才推送下2条消息,即使其他使用者是自由的并准备使用。 / p>

有关此问题的更多背景信息:

为什么一次只能处理2条消息? : Q2消息正在进行Web服务呼叫,并且Web服务端点(第三方)只能同时服务2条消息。

不能使用并发吗? : 如果我们使用ListenerContainer(Spring AMQP),则该容器是每个使用者的容器。我们可以限制一个使用者一次可以接收多少条消息,但是当我们有10个使用者时,如果队列中有消息,则每个使用者都将获得其份额。

我们可以仅配置2个消费者收听Q2吗? : 我知道我们可以通过为Q2仅配置2个使用者来实现此目的,但我试图避免这种情况。如果这两个消耗方由于某种原因而中断,则将停止Q2的处理。如果配置了10个使用者,我们可以保证处理将持续到最后一个使用者关闭为止。

希望查看RabbitMQ中是否可以使用某些配置或任何建议的解决方案。

谢谢!

3 个答案:

答案 0 :(得分:1)

我很确定consumer prefetch将完成您想要的。但是,第二季度只有一个消费者可以使用。无法在多个消费者之间进行协调-您必须自己做,并且可以使用RabbitMQ进行协调。


注意: RabbitMQ团队监视rabbitmq-users mailing list,并且有时仅在StackOverflow上回答问题。

答案 1 :(得分:0)

我认为您已经被问题定义所困扰。您真正需要的是微不足道的,所以让我们分解一下。

给出两个队列Q1Q2

  • 10个消费者
  • 每个消费者都可以处理来自第一季度和第二季度的消息。
  • 在任何给定时间,只有2个使用者应处理来自第二季度的消息。
  • 所有10个使用者都可以同时处理来自Q1的消息。

对问题陈述的评论

首先,假定队列是独立的。一个独立的进程P将具有队列Q,因此Q1为进程P1提供服务。这是一个严格的数学要求-您不能为单个进程P定义两个队列。

因此,第二个约束在数学上是不正确的,出于同样的原因,您不能编写一个有效的函数来接受类型为stringbool的参数。它必须接受一个或另一个,因为它们不是兼容类型,或者它必须接受类型的单个公共祖先,而不考虑子类型。这是Liskov Substitution Principle的变体。

重新定义问题

系统中共有12个使用者:

  • Q1有10个消费者
  • Q2有2个消费者
  • [重要]队列之间不共享使用方
  

RabbitMQ中是否可以指定任何配置,因此RabbitMQ仅将来自第2季度的2条消息推送到任何免费使用者,并在确认它们后才推送下2条消息,即使其他使用者是自由的并准备使用。 / p>

根据问题的新定义,您有两个选择:

  1. 使用Basic.Get-使用者完成对最后一条消息的处理后,立即从队列中提取下一条消息。
  2. 使用限制为1的consumer prefetch。这将立即为每个消费者传递第一条消息和第二条消息,然后在确认该消费者的下一条消息时一次传递一条附加消息。这有点复杂,但是如果您的等待时间余量小于10毫秒,则可能有意义。

请注意,通过正确定义问题空间,我们消除了一个基本问题,即试图弄清楚如何确保只有两个使用者在任何时候都处理Q2消息。

答案 2 :(得分:0)

尝试3.8版以上的新功能“单一活动使用者”。

单个活动的消费者每次只能从队列中消费一个消费者,并在活动的消费者被取消或死亡的情况下故障转移到另一个注册的消费者。 当必须按照消息到达队列的顺序来使用和处理消息时,仅与一个使用者一起使用很有用。 声明队列时可以启用单个活动使用者,并且x-single-active-consumer参数设置为true

https://www.rabbitmq.com/consumers.html#single-active-consumer

e.g. with the Java client: