因此,我们有一个kubernetes集群,运行一些带有芹菜工作者的pod。我们使用python3.6来运行这些工人,芹菜版本是3.1.2(我知道,真的很旧,我们正在升级它(。我们还设置了一些自动缩放机制,以增加更多的芹菜工人。
问题如下。假设我们在任何时候都有5个工人。然后很多任务就来了,增加了pod的CPU/RAM使用量。这会触发一个自动缩放事件,比如说,再添加两个芹菜荚。因此,现在这两位新的芹菜工人承担了一些长期的任务。在他们完成这些任务之前,kubernetes创建了一个缩小规模的事件,杀死了这两个工人,也杀死了那些长时间运行的任务。
此外,由于遗留的原因,如果任务没有完成,我们没有重试机制(我们现在无法实现(。
因此,我的问题是,有没有一种方法可以告诉kubernetes等待芹菜工作者运行所有挂起的任务?我想解决方案必须包括某种方式来通知芹菜工人,使其也停止接收新任务。现在我知道Kubernetes有一些脚本来处理这种情况,但我不知道在这些脚本上写什么,因为我不知道如何让芹菜工人停止接收任务。
知道吗?
我写了一篇关于这个主题的博客文章-看看吧。
当Kubernetes决定杀死一个pod时,它首先发送SIGTERM信号,这样你的应用程序就有时间优雅地关闭,之后如果你的应用没有结束,Kubernets会通过发送SIGKILL信号来杀死它。
SIGTERM到SIGKILL之间的这段时间可以通过terminationGracePeriodSeconds
进行调整(此处详细介绍(。
换句话说,如果你最长的任务需要5分钟,请确保将该值设置为高于300秒的值。
Celery为您处理这些信号,正如您在这里看到的那样(我想它也与您的版本相关(:
应使用TERM信号完成停机。
启动关闭时,工作程序将完成当前所有操作在它实际终止之前执行任务。如果这些任务重要的是,你应该等它结束后再做任何事情激烈的,比如发送KILL信号。
如文档中所述,您可以设置acks_late=True
配置,以便在任务意外停止时再次运行。
另一件我没有找到文档的事情(几乎可以肯定我在某个地方看到了它(——Celery工作人员在获得SIGTERM后不会收到新任务——所以你应该可以安全地终止该工作人员(可能还需要设置worker_prefetch_multiplier = 1
(。