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

时间:2012-03-10 00:13:24

标签: django linux celery pid 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)并立即死亡。 (这看起来像芹菜本身的一个错误;我let them know就此而言。)
  • 将SIGTERM发送到主进程,然后立即启动新实例:与Pidfile相同的问题。
  • 完全禁用Pid文件:如果没有它,我们无法告诉30个Celery进程中哪一个是我们希望它进行热关机时需要发送SIGTERM的主要进程。我们也没有可靠的方法来检查主要流程是否仍然存在。

7 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:3)

我最近使用SIGHUP修复了错误:https://github.com/celery/celery/pull/662

答案 2 :(得分:2)

rm *.pyc

这会导致重新加载更新的任务。我最近发现了这个技巧,我只希望没有令人讨厌的副作用。

答案 3 :(得分:1)

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

为我工作

答案 4 :(得分:0)

可以使用自定义pid文件名启动它吗?可能是时间戳,关键是知道要杀死哪个PID?

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

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

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

答案 5 :(得分:0)

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

答案 6 :(得分:0)

我想你可以试试这个:

kill -s HUP ``cat /var/run/celeryd.pid`` 
python manage.py celeryd --pidfile=/var/run/celeryd.pid

HUP可以回收每个免费工作人员并使执行工作人员继续运行,HUP将让这些工作人员受到信任。然后,您可以安全地重新启动新的芹菜工人主流程和工作人员。任务完成后,老工人可能会被自杀。

我在生产中使用这种方式,现在似乎很安全。希望这可以帮到你!