我在Celery中保留了数百万个任务(ETA尚未到期),每次我想更新我的Celery代码库时,我必须重新启动它,这会切断与RabbitMQ的连接并导致RabbitMQ再次重新分配任务(I我正在使用晚期的ack)。
是否可以重新加载新的代码库但仍保留我保留的任务?我正在使用带有Django的Celery。
答案 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
完成工作后,您就可以清楚地部署代码,而不必担心丢失任务。