如何解决在 ECS 中为 Celery 部署策略
我们目前在 ECS 中部署 Celery 的方式是在每次代码更改时调用 update-service。就将旧代码替换为新代码而言,这很有效。
有问题的场景是当我们有长时间运行的 Celery 任务时,部署会导致这些任务被杀死。这是因为 ECS 只给容器 30 秒的关闭时间(您可以将其增加到 10 分钟,但在某些情况下,即使这样也不够长)。被杀死的 Celery 任务确实会被新的 Celery worker 成功重启,但是你可以想象如果你每小时部署一次,你的任务需要 1.5 小时才能完成,它永远不会完成。
理想情况下,部署会告诉现有的 Celery 工作人员正常停止,即完成正在运行的任务但不要启动任何新任务。然后它将使用新代码启动新的工作容器,因此您可以同时运行旧的和新的。然后,当长时间运行的任务完成后,带有旧代码的容器将被删除。
这似乎是其他人一定遇到过的问题,但我找不到任何描述此问题的内容。编写脚本可能不会太糟糕,但感觉就像我们会围绕 ECS 来做这件事。任何帮助解决这个问题的指针或想法都会很棒。谢谢!
解决方法
好吧,我们最终采用的方法是在我们的部署过程中显式调用 worker 上的 shutdown 方法,而不是通过 ECS 进行部署,效果很好。
class Command(BaseCommand):
help = "Shutdown sunflower worker"
def handle(self,*args: Any,**options: Any) -> Optional[str]:
logger.info("Shutting down sunflower worker")
app.default_app.control.shutdown()
这解决了超时问题,并允许任何正在运行的任务继续运行。当每个任务完成时,worker 将停止(任何没有运行任务的 worker 将立即停止)。我们在 ECS 中设置了我们的任务定义以始终使用最新的容器,因此当它重新启动时,它相当于进行了一次部署。
您失去了 ECS 部署的一些优点,但它足够接近,而且绝对比杀死长时间运行的任务要好。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。