Django和Celery - 在更改后将代码重新加载到Celery中

问题描述 投票:18回答:3

如果我在芹菜运行时对tasks.py进行了更改,是否有一种机制可以重新加载更新的代码?或者我必须关闭芹菜重新装载?

我读过芹菜在旧版本中有一个--autoreload参数,但我在当前版本中找不到它:

celery: error: unrecognized arguments: --autoreload

django celery django-celery
3个回答
31
投票

不幸的是--autoreload不起作用,它是deprecated

你可以使用Watchdog来监视我做一个shell实用程序来执行基于文件事件的操作。

pip install watchdog

你可以开始工作

watchmedo auto-restart -- celery worker -l info -A foo

默认情况下,它将监视当前目录中的所有文件。这些可以通过传递相应的参数来改变。

watchmedo auto-restart -d . -p '*.py' -- celery worker -l info -A foo

如果你正在使用django并且不想依赖看门狗,那么有一个简单的技巧可以实现这一点。 Django具有自动重载实用程序,当代码更改时,runserver将使用该实用程序重新启动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,它将在代码库更改时自动加载。

这仅用于开发目的,不在生产中使用。


2
投票

仅供参考,对于任何使用Docker的人来说,我找不到一个简单的方法来使上述选项有效,但我发现(以及其他人)另一个小脚本here,它确实使用看门狗并且工作得很好。

将它保存为主目录中的some_name.py文件,将pip install psutil和watchdog添加到requirements.txt,更新顶部的路径/ cmdline变量,然后在docker-compose.yml插入的worker容器中:

command: python ./some_name.py

1
投票

您可以在父工作进程上尝试SIGHUP,它会重新启动工作程序,但我不确定它是否会接收新任务。值得一试,想:)

© www.soinside.com 2019 - 2024. All rights reserved.