重新加载芹菜代码而不会丢失保留任务

时间:2017-05-04 21:03:23

标签: python rabbitmq celery django-celery

我在Celery中保留了数百万个任务(ETA尚未到期),每次我想更新我的Celery代码库时,我必须重新启动它,这会切断与RabbitMQ的连接并导致RabbitMQ再次重新分配任务(I我正在使用晚期的ack)。

是否可以重新加载新的代码库但仍保留我保留的任务?我正在使用带有Django的Celery。

1 个答案:

答案 0 :(得分:1)

简短的回答:是的,可以,但是您必须编写自己的队列消耗逻辑。

更长的答案:当您想进行代码更新时(并取决于您的处理方式),您必须使用芹菜remote control api来告诉所有工作人员停止执行任务。 RabbitMQ代理支持远程控制API so you're in luck

from my_app.celery import app
inspector = app.control.inspect()
controller = app.control

# get a list of current workers
workers = inspector.ping()
active_queues = inspector.active_queues()
all_queues = set()
for worker, queues in active_queues.items():
    for queue in queues:
        all_queues.add(queue['name'])
for queue in all_queues:
    controller.cancel_consumer(queue)

这将阻止您的工作人员执行任务。现在,您必须监视您的工作人员,直到他们完成所有活动任务为止。

import time
done = False
while not done:
    active_count = 0
    active = inspector.active()
    active_count = sum(map(lambda l: len(l), active.values()))
    done = active_count > 0
    if not done:  
        time.sleep(60)  # wait a minute between checks

完成工作后,您就可以清楚地部署代码,而不必担心丢失任务。