【问题标题】:Celery - Check if worker received SIGTERM芹菜 - 检查工人是否收到 SIGTERM
【发布时间】:2021-07-24 10:02:55
【问题描述】:

我有一个很长的Celery 任务。超过几分钟。

有时,由于各种原因,一个工人被标记为终止,而另一个工人开始。如果需要更换运行它的机器,或者正在部署新的代码版本,就会发生这种情况。在这种情况下,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

【问题讨论】:

    标签: python celery celery-task


    【解决方案1】:

    当 Celery worker 收到 SIGTERM 时,它将启动 热关机。这意味着它将取消自己从所有队列中的订阅,预取的任务(如果有的话)将返回到它们的队列中,并且 worker 本身将开始等待当前正在运行的任务完成,然后再关闭。没有任务会丢失,如果那是您所担心的。

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

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

    【讨论】:

    • 我稍后会编辑问题以使其更清晰。但问题是任务本身是否可以检查它正在运行的工作人员是否在热关闭流程中
    • 很简单,处理信号,并在某处存储一个标志(例如工人的配置),以便任务可以检查标志并进行一些内部处理......我谦虚地认为任务不应该做这个,而不是让工人重新排队,或类似的......
    • 配置不起作用... Redis 可能是最好的选择。我已经用这种方法更新了我的答案。
    • 当容器关闭时我根本没有收到worker_shutting_down 信号。在 AWS ECS 上通过 docker 运行 celery。有什么线索吗?我在 docker 中直接以 CMD 运行 celery -A ...,所以我认为它应该得到信号,不是吗?
    • 更新:事实证明,您需要使用 ["bash","-c","celery -A ..."] 作为 CMD 来获取信号,以便在 Docker 中向您的 celery worker 发送信号。我希望这对尝试在 Docker 中执行此操作的人们有所帮助。我在 tini 和其他 init 程序中苦苦挣扎,只是为了意识到 bash 非常好!
    【解决方案2】:

    我能问一下你为什么要做这样的事情吗?你启用task_acks_late了吗?这样,如果一项任务无法按时完成并且工作人员将关闭,则该任务将在新工作人员上重新运行。

    这里是documentation。还有task_reject_on_worker_lost,我没试过,但也许对你也有帮助:

    将此设置为 true 允许消息重新排队,因此 该任务将由同一个工作人员或另一个工作人员再次执行 工人。

    【讨论】:

    • ack_late的问题是需要等待超时完成。因此,如果任务有 60 分钟的超时,但 2 分钟后需要终止,那么 ack_late 只会在 58 分钟后将其放回队列中。但是如果任务可以检测到它正在终止,它可以将它放回队列中
    • 能否详细说明如何定义和使用超时时间?
    • 我用任务的长度来定义。例如,如果我知道某项任务需要大约 60 分钟,我会将超时定义为 70-90 分钟
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-22
    • 2019-08-01
    • 2014-08-17
    • 1970-01-01
    • 2022-01-08
    相关资源
    最近更新 更多