如何在不延迟任务的情况下优雅地重新启动Celery

nit*_*wit 24 linux django pid celery celeryd

我们使用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实例来开始运行新任务.

事情并没有工作:

  • 将SIGHUP发送到主进程:这导致Celery尝试通过执行热关闭然后重新启动来"重启".这不仅需要很长时间,甚至还不起作用,因为显然新工艺在旧工艺死亡之前启动,因此新工艺会ERROR: Pidfile (/var/run/celeryd.pid) already exists. Seems we're already running? (PID: 13214)立即抱怨并死亡.(这看起来像芹菜本身的一个错误;我让他们知道它.)
  • 将SIGTERM发送到主进程,然后立即启动新实例:与Pidfile相同的问题.
  • 完全禁用Pid文件:如果没有它,我们无法告诉30个Celery进程中哪一个是我们希望它进行热关闭时需要发送SIGTERM的主要进程.我们也没有可靠的方法来检查主要过程是否仍然存在.

mhe*_*her 5

celeryd 有 --autoreload 选项。如果启用,celery worker(主进程)将检测 celery 模块中的更改并重新启动所有工作进程。与 SIGHUP 信号相反,autoreload 在当前执行的任务完成时独立地重新启动每个进程。这意味着当一个工作进程正在重新启动时,其余进程可以执行任务。

http://celery.readthedocs.org/en/latest/userguide/workers.html#autoreloading

  • 尽管 `--autoreload` 被标记为不建议用于实时部署。 (14认同)

j_m*_*lly 0

您可以使用自定义 pid 文件名启动它吗?可能带有时间戳,然后关闭它就知道要杀死哪个 PID?

CELERYD_PID_FILE="/var/run/celery/%n_{timestamp}.pid"

^我不知道时间戳语法,但也许你知道或者你可以找到它?

然后使用当前系统时间杀死所有旧的 pid 并启动一个新的?