也许我在愚蠢地提出问题,但在进一步开展工作之前,我需要先了解基本概念。
我正在使用多个Celery工作节点和RabbitMQ节点作为代理处理几千个RSS源。每个订阅源的URL都作为消息写入队列中。工作人员只是从队列中读取URL并开始处理它。 我必须确保两个工作人员不会同时处理单个RSS源。
文章Ensuring a task is only executed one at a time建议使用基于Memcahced的解决方案,以便在处理Feed时锁定Feed。
但我想要了解的是,为什么我需要使用Memcached(或其他东西)来确保RabbitMQ队列上的消息不会被多个worker同时使用。 RabbitMQ(或Celery)中是否有一些配置更改可以实现此目标?
答案 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
操作(只能设置一次键)。