Celery - RabbitMQ中的消息可以同时由两个或更多工人消费吗?

时间:2012-08-28 05:52:36

标签: python rabbitmq celery django-celery

也许我在愚蠢地提出问题,但在进一步开展工作之前,我需要先了解基本概念。

我正在使用多个Celery工作节点和RabbitMQ节点作为代理处理几千个RSS源。每个订阅源的URL都作为消息写入队列中。工作人员只是从队列中读取URL并开始处理它。 我必须确保两个工作人员不会同时处理单个RSS源。

文章Ensuring a task is only executed one at a time建议使用基于Memcahced的解决方案,以便在处理Feed时锁定Feed。

但我想要了解的是,为什么我需要使用Memcached(或其他东西)来确保RabbitMQ队列上的消息不会被多个worker同时使用。 RabbitMQ(或Celery)中是否有一些配置更改可以实现此目标?

3 个答案:

答案 0 :(得分:5)

在正常工作设置中,多个消费者肯定不会看到单个MQ消息。你必须为涉及失败/崩溃工人的案件做一些工作,阅读自动确认和消息拒绝,但基本情况是合理的。

我没有在您链接的文章中看到同步队列(读取:MQ),因此(据我所知)他们正在使用锁定机制(读取:memcache)进行同步,替代。我可以想到一些在适当的MQ设置中不存在的问题。

答案 1 :(得分:4)

正如其他人所说,你正在搅拌苹果和橘子。

作为芹菜任务和MQ消息。

您可以确保只有一个工作人员同时处理邮件。

例如

@task(...)
def my_task(

my_task.apply(1)

.apply向您正在使用的消息代理发布消息(rabbit,redis ...)。 然后,消息将被路由到队列并由一个工作人员消耗。你不需要为此锁定,你可以免费使用它:)

celery cookbook上的示例显示了如何防止这样的两条消息(my_task.apply(1))同时运行,这是您需要在任务本身内确保的。

您需要一些可以从所有工作人员访问的东西(memcached,redis ......),因为它们可能在不同的机器上运行。

答案 2 :(得分:2)

提到的示例通常用于其他目标:它​​会阻止您使用具有相同含义的不同消息(不是相同的消息)。例如,我有两个进程:第一个用于排队某些URL,第二个用于从队列中获取URL并获取它们。如果第一个进程将一个URL排队两次(或甚至更多次),将会是什么?

P.S。我出于此目的使用Redis存储和setnx操作(只能设置一次键)。