Django 和 Celery - 更改后将代码重新加载到 Celery
Django and Celery - re-loading code into Celery after a change
如果我在 celery 为 运行 时更改 tasks.py,是否有一种机制可以重新加载更新后的代码?还是我必须关闭 Celery 重新加载?
我读到芹菜在旧版本中有一个 --autoreload
参数,但我在当前版本中找不到它:
celery: error: unrecognized arguments: --autoreload
您可以在父工作进程上尝试 SIGHUP,它会重新启动工作进程,但我不确定它是否会接收新任务。值得一试,认为 :)
不幸的是 --autoreload
不起作用,它是 deprecated。
您可以使用提供 watchmedo shell 实用程序的 Watchdog 来根据文件事件执行操作。
pip install watchdog
您可以使用
启动 worker
watchmedo auto-restart -- celery worker -l info -A foo
默认情况下,它将监视当前目录中的所有文件。这些可以通过传递相应的参数来改变。
watchmedo auto-restart -d . -p '*.py' -- celery worker -l info -A foo
添加 -R
选项以递归查看文件。
如果您使用的是 django 并且不想依赖看门狗,可以使用一个简单的技巧来实现。 Django 有自动重载实用程序,运行服务器使用它在代码更改时重新启动 WSGI 服务器。
可以使用相同的功能重新加载芹菜工人。创建一个名为 celery 的单独管理命令。编写一个函数来杀死现有的 worker 并启动一个新的 worker。现在将此函数挂接到 autoreload,如下所示。对于 Django >= 2.2
import sys
import shlex
import subprocess
from django.core.management.base import BaseCommand
from django.utils import autoreload
class Command(BaseCommand):
def handle(self, *args, **options):
autoreload.run_with_reloader(self._restart_celery)
@classmethod
def _restart_celery(cls):
if sys.platform == "win32":
cls.run('taskkill /f /t /im celery.exe')
cls.run('celery -A phoenix worker --loglevel=info --pool=solo')
else: # probably ok for linux2, cygwin and darwin. Not sure about os2, os2emx, riscos and atheos
cls.run('pkill celery')
cls.run('celery worker -l info -A foo')
@staticmethod
def run(cmd):
subprocess.call(shlex.split(cmd))
对于 django < 2.2
import sys
import shlex
import subprocess
from django.core.management.base import BaseCommand
from django.utils import autoreload
class Command(BaseCommand):
def handle(self, *args, **options):
autoreload.main(self._restart_celery)
@classmethod
def _restart_celery(cls):
if sys.platform == "win32":
cls.run('taskkill /f /t /im celery.exe')
cls.run('celery -A phoenix worker --loglevel=info --pool=solo')
else: # probably ok for linux2, cygwin and darwin. Not sure about os2, os2emx, riscos and atheos
cls.run('pkill celery')
cls.run('celery worker -l info -A foo')
@staticmethod
def run(cmd):
subprocess.call(shlex.split(cmd))
现在您可以 运行 使用 python manage.py celery
的 celery worker,它会在代码库更改时自动重新加载。
这仅用于开发目的,请勿在生产中使用。
仅供参考,对于使用 Docker 的任何人,我找不到使上述选项起作用的简单方法,但我发现(与其他人一起)另一个确实使用的小脚本 here看门狗,工作完美。
在你的主目录下保存为some_name.py
文件,添加pip install psutil和watchdog到requirements.txt
,更新顶部的path/cmdline变量,然后在worker容器中你的 docker-compose.yml 插入:
command: python ./some_name.py
Watchmedog 在 docker 容器中对我不起作用。
这是我使用 Django 的方式:
# worker_dev.py (put it next to manage.py)
from django.utils import autoreload
def run_celery():
from projectname import celery_app
celery_app.worker_main(["-Aprojectname", "-linfo", "-Psolo"])
print("Starting celery worker with autoreload...")
autoreload.run_with_reloader(run_celery)
然后 运行 python worker_dev.py
或将其设置为您的 Dockerfile CMD
或 docker-compose command
.
如果我在 celery 为 运行 时更改 tasks.py,是否有一种机制可以重新加载更新后的代码?还是我必须关闭 Celery 重新加载?
我读到芹菜在旧版本中有一个 --autoreload
参数,但我在当前版本中找不到它:
celery: error: unrecognized arguments: --autoreload
您可以在父工作进程上尝试 SIGHUP,它会重新启动工作进程,但我不确定它是否会接收新任务。值得一试,认为 :)
不幸的是 --autoreload
不起作用,它是 deprecated。
您可以使用提供 watchmedo shell 实用程序的 Watchdog 来根据文件事件执行操作。
pip install watchdog
您可以使用
启动 workerwatchmedo auto-restart -- celery worker -l info -A foo
默认情况下,它将监视当前目录中的所有文件。这些可以通过传递相应的参数来改变。
watchmedo auto-restart -d . -p '*.py' -- celery worker -l info -A foo
添加 -R
选项以递归查看文件。
如果您使用的是 django 并且不想依赖看门狗,可以使用一个简单的技巧来实现。 Django 有自动重载实用程序,运行服务器使用它在代码更改时重新启动 WSGI 服务器。
可以使用相同的功能重新加载芹菜工人。创建一个名为 celery 的单独管理命令。编写一个函数来杀死现有的 worker 并启动一个新的 worker。现在将此函数挂接到 autoreload,如下所示。对于 Django >= 2.2
import sys
import shlex
import subprocess
from django.core.management.base import BaseCommand
from django.utils import autoreload
class Command(BaseCommand):
def handle(self, *args, **options):
autoreload.run_with_reloader(self._restart_celery)
@classmethod
def _restart_celery(cls):
if sys.platform == "win32":
cls.run('taskkill /f /t /im celery.exe')
cls.run('celery -A phoenix worker --loglevel=info --pool=solo')
else: # probably ok for linux2, cygwin and darwin. Not sure about os2, os2emx, riscos and atheos
cls.run('pkill celery')
cls.run('celery worker -l info -A foo')
@staticmethod
def run(cmd):
subprocess.call(shlex.split(cmd))
对于 django < 2.2
import sys
import shlex
import subprocess
from django.core.management.base import BaseCommand
from django.utils import autoreload
class Command(BaseCommand):
def handle(self, *args, **options):
autoreload.main(self._restart_celery)
@classmethod
def _restart_celery(cls):
if sys.platform == "win32":
cls.run('taskkill /f /t /im celery.exe')
cls.run('celery -A phoenix worker --loglevel=info --pool=solo')
else: # probably ok for linux2, cygwin and darwin. Not sure about os2, os2emx, riscos and atheos
cls.run('pkill celery')
cls.run('celery worker -l info -A foo')
@staticmethod
def run(cmd):
subprocess.call(shlex.split(cmd))
现在您可以 运行 使用 python manage.py celery
的 celery worker,它会在代码库更改时自动重新加载。
这仅用于开发目的,请勿在生产中使用。
仅供参考,对于使用 Docker 的任何人,我找不到使上述选项起作用的简单方法,但我发现(与其他人一起)另一个确实使用的小脚本 here看门狗,工作完美。
在你的主目录下保存为some_name.py
文件,添加pip install psutil和watchdog到requirements.txt
,更新顶部的path/cmdline变量,然后在worker容器中你的 docker-compose.yml 插入:
command: python ./some_name.py
Watchmedog 在 docker 容器中对我不起作用。
这是我使用 Django 的方式:
# worker_dev.py (put it next to manage.py)
from django.utils import autoreload
def run_celery():
from projectname import celery_app
celery_app.worker_main(["-Aprojectname", "-linfo", "-Psolo"])
print("Starting celery worker with autoreload...")
autoreload.run_with_reloader(run_celery)
然后 运行 python worker_dev.py
或将其设置为您的 Dockerfile CMD
或 docker-compose command
.