芹菜 - 检查工人是否收到 SIGTERM

Celery - Check if worker received SIGTERM

我有一个 Celery 任务很长。不止几分钟。

有时,由于各种原因,一个worker被标记为终止而另一个worker开始。如果需要更换运行它的机器,或者正在部署新的代码版本,就会发生这种情况。在这种情况下,工作人员会收到 SIGTERM 信号。

我想知道任务本身是否有可能定期检查此工作人员是否已收到 SIGTERM 并且正在等待终止,在这种情况下只需将任务放回队列并终止。 (然后该任务将在另一个工作人员上启动,并将继续执行其工作)

编辑:澄清 - 是否可以在任务中检查它是否在等待终止的工作人员上执行。像这样:

# Some long task that can take even a few hours.
def some_task(...):
    for i in range(...):
        do_some_work()
        # That's the missing function:
        if did_this_worker_received_SIGTERM_and_waiting_to_be_terminated():
             # stop the task in the middle, and it will be executed again later

当 Celery worker 收到 SIGTERM 时,它将启动 暖关机。这意味着它将取消订阅所有队列,预取任务(如果有的话)将返回到它们的队列,并且 worker 本身将开始等待当前 运行 个任务完成,然后关闭。没有任务会丢失,如果那是你害怕的话。

所有这些事件都可以处理(参见Worker Signals)。

如果你仍然坚持在你的任务中有一些额外的逻辑来处理工作状态,那么最简单的解决方案可能是实现工作关闭处理程序(如我上面提到的文档部分中所述),让它存储一个标志在 Redis 或其他一些分布式 K/V 存储中),并重构需要它的任务,以便它们访问此标志并执行您需要它们执行的任何操作。

请问你为什么要做这样的事情?您是否启用了 task_acks_late?这样,如果任务无法按时完成并且工作人员将关闭,任务将在新工作人员上再次运行。

这是我没试过的documentation. There's also task_reject_on_worker_lost,但也许它也能帮到你:

Setting this to true allows the message to be re-queued instead, so that the task will execute again by the same worker, or another worker.