使用RabbitMq锁定和批量获取消息

时间:2012-01-24 10:57:45

标签: message-queue rabbitmq amqp

我正在尝试以更加非常规的方式使用RabbitMq(尽管此时我可以根据需要选择任何其他消息队列实现)。消费者不是将Rabbit推送消息留给我的消费者,而是连接到队列并获取一批N个消息(在此期间消耗一些消息并且可能拒绝一些消息),然后它跳转到另一个队列,依此类推。这样做是为了冗余。如果某些消费者崩溃,则保证所有消息都被其他消费者消费。

问题在于我有多个消费者,我不希望他们在同一个队列中竞争。有没有办法保证队列锁定?如果没有,我是否至少可以确保如果2个消费者连接到同一个队列,他们不会读取相同的消息?交易可能在某种程度上帮助了我,但我听说他们将从RabbitMQ中删除。

其他建筑建议也受到欢迎。

谢谢!

修改 正如评论中所指出的那样,我需要如何处理消息。它们只在组中有意义,并且相关消息很可能在队列中聚集在一起。例如,如果我拉了一批100条消息,那么很有可能我会对1-3,4-5,6-10等消息做一些事情。如果我找不到某些消息的组,我将他们重新提交到队列中。 WorkQueue不起作用,因为它会将来自同一组的消息传播给不知道如何处理它们的多个工作人员。

3 个答案:

答案 0 :(得分:8)

您是否看过Enterprise Integration Patterns这本免费在线图书?

听起来你真的需要一个工作流程,在消息传递给你的工作人员之前你有一个batcher组件。使用RabbitMQ有两种方法可以做到这一点。使用可以为您进行批处理的交换类型(和消息格式),或者有一个队列,以及一个工作人员,可以对批次进行分类并将每个批处理放在自己的队列中。配料机也应该发送批量准备好的#34;消息到控制队列,以便工作人员可以发现新批处理队列的存在。处理批处理后,工作人员可以删除批处理队列。

如果您可以控制消息格式,您可以通过几种方式隐式地使RabbitMQ进行批处理。通过主题交换,您可以确保每条消息上的路由键的格式为work.batchid.something,然后了解批处理xxyzz存在的工作人员将使用#.xxyzz等#绑定键。消费这些消息。不需要重新发布。

另一种方法是在标头中包含批处理ID并使用较新的标头交换类型。当然,如果您愿意编写少量的Erlang代码,也可以实现自己的自定义交换类型。

我建议检查一下这本书,因为它提供了比大多数人开始的典型工作队列概念更好的消息传递体系结构概述。

答案 1 :(得分:2)

让您的消费者从一个队列中拉出来。他们将保证不共享消息(Rabbit将在当前连接的消费者中循环消息)并且针对该确切的使用模式进行了大量优化。

它随时可用,开箱即用。在RabbitMQ文档中,它被称为Work Queue模型。一个队列,多个消费者,他们都没有共享任何东西。这听起来像你需要的。

答案 2 :(得分:0)

您可以设置通道/使用者级别预取计数以批量使用消息。为了重新提交消息,您应该使用basic.reject AMQP方法,并且可以选择将这些消息重新排队或转发到死信队列。尝试从同一队列中提取消息的多个消费者不会成为AMQP basic.get方法同步处理并发消费者的问题。

https://groups.google.com/forum/#!topic/rabbitmq-users/hJ8f5du-GCA