我们使用 Celery 和 Django webapp 来管理离线任务;其中一些任务可以运行长达 120 秒。
每当我们进行任何代码修改时,我们都需要重新启动 Celery 以让它重新加载新的 Python 代码。我们当前的解决方案是向 Celery 主进程发送一个 SIGTERM(kill -s 15 `cat /var/run/celeryd.pid`
),然后等待它死亡并重新启动它(python manage.py celeryd --pidfile=/var/run/celeryd.pid [...]
)。
由于长时间运行的任务,这通常意味着关闭将需要一两分钟,在此期间不会处理任何新任务,从而对当前在站点上的用户造成明显的延迟。我正在寻找一种方法来告诉 Celery 关闭,然后立即启动一个新的 Celery 实例以开始运行新任务。
没用的东西:
- 发送 SIGHUP 到主进程:这导致 Celery 尝试“重启”,方法是热关机然后重新启动自身。这不仅需要很长时间,甚至不起作用,因为显然新进程在旧进程死亡之前启动,所以新进程抱怨
ERROR: Pidfile (/var/run/celeryd.pid) already exists. Seems we're already running? (PID: 13214)
并立即死亡。(这看起来像是 Celery 本身的一个错误;我已经让他们知道了。) - 将 SIGTERM 发送到主进程,然后立即启动一个新实例:与 Pidfile 相同的问题。
- 完全禁用 Pidfile:没有它,我们无法判断 30 个 Celery 进程中的哪一个是需要发送 SIGTERM 的主进程,当我们希望它进行热关机时。我们也没有可靠的方法来检查主进程是否还活着。