24

我们使用 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 的主进程,当我们希望它进行热关机时。我们也没有可靠的方法来检查主进程是否还活着。
4

7 回答 7

5

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

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

于 2012-03-10T18:56:46.860 回答
3

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

于 2012-05-31T09:03:57.683 回答
2
rm *.pyc

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

于 2013-04-26T16:12:12.353 回答
1

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

于 2013-07-21T07:00:33.190 回答
0

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

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

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

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

于 2012-03-10T00:23:38.907 回答
0

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

我工作。

于 2014-12-10T17:47:09.787 回答
0

我想你可以试试这个:

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

HUP可能会回收每个空闲的工人,让执行工人继续运行,HUP并让这些工人得到信任。然后你可以安全地重新启动一个新的 celery worker 主进程和 worker。当任务完成时,老工人可能会被杀死。

我在我们的生产中使用过这种方式,现在看起来很安全。希望这可以帮到你!

于 2018-06-08T02:58:13.060 回答