如何在不延迟任务的情况下轻松重启Celery

我们在我们的Django webapp中使用Celery来pipe理离线任务; 其中一些任务可以运行长达120秒。

每当我们做任何代码修改,我们需要重新启动芹菜重新加载新的Python代码。 我们目前的解决scheme是发送一个SIGTERM到主Celery进程( kill -s 15 `cat /var/run/celeryd.pid` ),然后等待它死掉并重新启动它( python manage.py celeryd --pidfile=/var/run/celeryd.pid [...] )。

由于长时间运行的任务,这通常意味着关机将花费一两分钟的时间,在此期间不会处理新的任务,从而导致当前站点上的用户明显延迟。 我正在寻找一种方法告诉Celeryclosures,但是立即启动一个新的Celery实例来开始运行新的任务。

事情没有工作:

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

Solutions Collecting From Web of "如何在不延迟任务的情况下轻松重启Celery"

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

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

我最近用SIGHUP修正了这个bug: https : //github.com/celery/celery/pull/662

 rm *.pyc 

这会导致更新的任务重新加载。 最近我发现了这个伎俩,我只是希望没有不好的副作用。

有点晚,但可以通过删除名为celerybeat.pid的文件来修复

为我工作。

你可以用一个自定义的pid文件名来启动它吗? 可能的时间戳,并关键的知道哪个PID杀死?

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

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

那么使用当前的系统时间来杀掉任何旧的pid并启动一个新的pid?

那么你使用SIGHUP(1)芹菜热关机。 我不确定是否真的会导致热关机。 但是SIGINT(2)会导致热关机。 尝试SIGINT代替SIGHUP,然后在脚本中手动启动芹菜(我猜)。