Python 检查芹菜温关机是否正在执行任务 TL;博士

Python 检查芹菜温关机是否正在执行任务 TL;博士,python,celery,Python,Celery,有没有办法判断我们的芹菜工人是否会进入热关机状态?换句话说,我可以检查是否有一个SIGTERM挂起吗?我有一个重新安排自己的任务,但我想避免重新安排自己,如果有一个关机等待,以避免拖延热关机。大概是这样的: if not self.shutdown_pending(): self.retry(countdown=5, max_retries=3) @app.task(bind=True) def my_work_task(self): work = get_work()

有没有办法判断我们的芹菜工人是否会进入热关机状态?换句话说,我可以检查是否有一个
SIGTERM
挂起吗?我有一个重新安排自己的任务,但我想避免重新安排自己,如果有一个关机等待,以避免拖延热关机。大概是这样的:

if not self.shutdown_pending():
    self.retry(countdown=5, max_retries=3)
@app.task(bind=True)
def my_work_task(self):
    work = get_work()
    do_some_work(work)
    # if this was just a short bit of work reschedule ourselves
    # immediately to avoid wasting time waiting for the
    # next celery beat.
    if len(work) < SMALL_WORK_THRESHOLD:
        self.retry(countdown=5, max_retries=3)
事实上,抛开重新安排的事情不谈,我希望在获得
SIGTERM
后能够彻底摆脱当前的工作,这样我就可以在新的代码部署上尽快重启我的工作人员:

@app.task(bind=True)
def my_work_task(self):
    work = get_work()
    for item in work:
        if self.shutdown_pending():
            logger.info("Shutdown detected. Bailing.")
            return
        item.process()

背景 我有一项任务,需要的时间不一(从几秒钟到几分钟不等)。我使用一个每分钟一次的芹菜节拍时间表来调用任务,但是如果我只做了少量的工作,比如说,10秒完成,然后我想立即重新调用任务几次,以避免等待50秒等待下一个芹菜节拍,因为新的工作很可能会在这段时间内可用

所有这些都是为了最大限度地减少处理工作项的延迟。我想避免50秒的时间,工人坐在那里什么也不做,因为在这段时间内可能会有一些工作可用。请注意,工作是基于数据库中项目的“过期”而“准备就绪”的,这就是为什么我使用芹菜节拍在项目可用时进行清理,而不是直接触发任务

我的任务如下所示:

if not self.shutdown_pending():
    self.retry(countdown=5, max_retries=3)
@app.task(bind=True)
def my_work_task(self):
    work = get_work()
    do_some_work(work)
    # if this was just a short bit of work reschedule ourselves
    # immediately to avoid wasting time waiting for the
    # next celery beat.
    if len(work) < SMALL_WORK_THRESHOLD:
        self.retry(countdown=5, max_retries=3)
@app.task(bind=True)
定义我的工作任务(自我):
工作=得到工作
做一些工作(工作)
#如果这只是一个小小的工作,我们自己重新安排吧
#立即避免浪费时间等待
#下一个芹菜节拍。
如果len(功)<小功阈值:
自我重试(倒计时=5,最大重试次数=3)

这一切都很好,除了一件事:当我重新加载我的工作人员(通过发送
SIGTERM
)时,我可能会等待一个工作人员重新安排自己,每次都可能有大量的工作。每次调用可能需要几分钟的时间,直到达到我的
max\u retries
值。这使得部署新代码成为一个问题,因为工作处理几乎会停止长达几分钟。

遗憾的是,没有一个像本文中提到的那样简单的解决方案

您唯一能做的就是更改方法或使用
SIGKILL
,在这种情况下,请确保使用任务结果后端来了解您可能丢失了哪些任务,或者如果您在数据库上保留了状态,则可能不需要它

根据我个人的经验,我总是使用mongodb来注册星星和任务的结束。这使我能够看到由于机器崩溃而无法完成的任务(我最近使用了CELERY_ACKS_),如果我希望某个任务在整个云上只运行一次,还可以执行全局锁定。 这样,如果SIGTERM在一段时间后不工作,我就发送了一个SIGKILL,而没有失去工作的风险

希望这有帮助