Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django 如何在不延迟任务的情况下优雅地重新启动芹菜_Django_Linux_Celery_Pid_Celeryd - Fatal编程技术网

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

Django 如何在不延迟任务的情况下优雅地重新启动芹菜,django,linux,celery,pid,celeryd,Django,Linux,Celery,Pid,Celeryd,我们在Django webapp中使用芹菜来管理离线任务;其中一些任务可以运行120秒 无论何时修改代码,我们都需要重新启动芹菜,让它重新加载新的Python代码。我们当前的解决方案是将SIGTERM发送到主芹菜进程(kill-s15`cat/var/run/celeryd.pid`),然后等待它死亡并重新启动它(python manage.py celeryd--pidfile=/var/run/celeryd.pid[…]) 由于任务长时间运行,这通常意味着关机将花费一两分钟,在此期间不会处

我们在Django webapp中使用芹菜来管理离线任务;其中一些任务可以运行120秒

无论何时修改代码,我们都需要重新启动芹菜,让它重新加载新的Python代码。我们当前的解决方案是将SIGTERM发送到主芹菜进程(
kill-s15`cat/var/run/celeryd.pid`
),然后等待它死亡并重新启动它(
python manage.py celeryd--pidfile=/var/run/celeryd.pid[…])

由于任务长时间运行,这通常意味着关机将花费一两分钟,在此期间不会处理新任务,这会对当前站点上的用户造成明显的延迟。我正在寻找一种方法,告诉芹菜关闭,然后立即启动一个新芹菜实例,开始运行新任务

不起作用的事情:

  • 将信号发送到主进程:这导致芹菜尝试“重启”,通过热关机,然后重新启动自身。这不仅需要很长时间,而且根本不起作用,因为显然新进程在旧进程死亡之前启动,所以新进程抱怨
    错误:Pidfile(/var/run/celeryd.pid)已经存在。看来我们已经在跑步了?(PID:13214)
    并立即死亡。(这看起来像芹菜里的虫子,我已经考虑过了。)
  • 将SIGTERM发送到主进程,然后立即启动一个新实例:Pidfile也有同样的问题
  • 完全禁用Pidfile:如果没有它,我们无法判断30芹菜进程中的哪个是主进程,当我们希望它进行热关机时,需要发送SIGTERM。我们也没有可靠的方法来检查主进程是否仍然有效

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

CELERYD\u PID\u FILE=“/var/run/celery/%n{timestamp}.PID”

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

然后使用当前的系统时间删除所有旧的PID并启动一个新的?

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


我最近用SIGHUP修复了这个错误:


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

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

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


对我有效。

我想你可以试试这个:

kill -s HUP ``cat /var/run/celeryd.pid`` 
python manage.py celeryd --pidfile=/var/run/celeryd.pid
HUP
可以回收所有空闲的工作人员,并让执行工作人员继续运行,
HUP
将让这些工作人员得到信任。然后您可以安全地重新启动一个新的芹菜工人主进程和工人。任务完成后,老工人可能会自杀


我在生产中使用过这种方法,现在看起来很安全。希望这能帮助你

虽然
--autoreload
被标记为不建议实时部署。但在生产中,它可以与像这样的自定义重新加载程序一起使用,我怀疑您需要将问题中的一种技术与此相结合。根据您的代理,您应该能够使用基于时间戳的PID文件(使用
--pidfile=
)启动一个新芹菜,然后将
SIGTERM
发送到所有其他正在运行的芹菜进程,以使其热关机(尽管请注意,实际上应该只有一个,除非您在旧芹菜仍处于热关机状态时尝试此操作)。谢谢!但是,您的修复程序并没有改变这样一个事实,即SIGHUP在终止和重新启动之前会等待所有任务完成,这再次导致我试图避免的延迟。有关如何利用您的修复程序并在不等待的情况下使其重新启动的想法将非常好……这就是我解决问题的方法。我将每个长时间运行的任务(视频转换、电子邮件发送)在一个单独的队列中,由一个单独的工作者处理。因此,当我向所有工作者发送SIGHUP时,我知道默认队列中处理任务的工作者不会阻塞很长时间,因为只有小任务。视频转换不会阻塞小任务。只有视频转换队列会阻塞一段时间。但这是可以接受的在我的例子中。经过一些测试,我发现您的修复程序也解决了SIGTERM问题。因此,我最终通过合并您的修复程序并使用以下命令重新启动芹菜来解决这个问题:
kill-s SIGTERM``cat/var/run/celeryd.pid`&&python manage.py celeryd--pidfile=/var/run/celeryd.pid[…]
如果你能在回答中提到这一点,我会接受的!我认为这是不可靠的。我的补丁有一个小错误-它过早地释放了一个PID锁(在所有任务完成之前)。因此,它允许在旧进程完全关闭之前启动新进程。这是完全不可靠的。当合并到主分支时,这是已修复的。您称之为SIGTERM的错误实际上不是错误。这只是每个守护进程的正常行为。因此,我强烈建议不要利用修补程序中的错误,而是使用固定版本:也许我的答案对你有帮助。
kill -s HUP ``cat /var/run/celeryd.pid`` 
python manage.py celeryd --pidfile=/var/run/celeryd.pid