我们使用Celery和我们的Django webapp来管理离线任务; 其中一些任务可以运行长达120秒.
每当我们进行任何代码修改时,我们都需要重新启动Celery以重新加载新的Python代码.我们当前的解决方案是将SIGTERM发送到主Celery进程(kill -s 15 `cat /var/run/celeryd.pid`),然后等待它死并重新启动它(python manage.py celeryd --pidfile=/var/run/celeryd.pid [...]).
由于长时间运行的任务,这通常意味着关闭将花费一两分钟,在此期间不会处理任何新任务,从而导致当前站点上的用户显着延迟.我正在寻找一种方法告诉Celery关闭,但随后立即启动一个新的Celery实例来开始运行新任务.
事情并没有工作:
ERROR: Pidfile (/var/run/celeryd.pid) already exists. Seems we're already running? (PID: 13214)立即抱怨并死亡.(这看起来像芹菜本身的一个错误;我让他们知道它.)我有一个 Flask 应用程序,允许用户通过 celery 作业队列启动长时间运行的任务(有时> 1d)。Flask 应用程序及其所有依赖项(包括 celery 工作人员)都通过 docker 进行容器化,并以 docker-compose 文件启动。
我的问题是,当我使用新版本的应用程序软件更新容器映像时,我需要使用以下命令重新启动容器:
docker-compose down
docker-compose up -d
Run Code Online (Sandbox Code Playgroud)
这将取消所有长时间运行的作业,因为 docker-compose 中默认只有一个很短的超时值。按照 docker- compose 和优雅的 Celery 关闭中的建议,为 docker-compose 的优雅停止设置更长的超时值对我来说不起作用,因为无法预测作业将花费多长时间,并且更新可能需要很长时间才能完成所有任务都已完成。
我的想法是以某种方式将正在运行的容器与docker-compose控件分离,然后在分离的容器内正常关闭 celery,然后允许作业完成,但不接受新作业。然后我可以通过启动正常的容器堆栈docker-compose up -d。
因此我想做:
我尝试使用docker rename重命名由 docker-compose 启动的容器,但它们仍然对docker-compose down.
我的问题是,这种方法是否是处理此问题的正确方法,以及 docker-compose 是否可以实现这一点?在 docker-compose 环境中处理长期运行任务的 celery 工作人员的优雅更新的最佳实践是什么?
我发现相关但没有完全解决问题的其他问题:
docker-compose 和优雅的 Celery shutdown:答案显示了如何优雅地停止容器,但我想立即启动一个新的 celery 工作程序,以免产生停机时间。
如何优雅地重新启动 celery 工作人员?:这适用于本地安装,但我必须重新启动容器才能获取新的应用程序代码。
编辑:解决方案的新提示: …
场景:
部署到生产是通过以下脚本完成的:
如何增强部署脚本以使其执行以下操作?: