Django и Celery. №2. Перезагрузка Celery при изменении кода

Вступление

Это # 2 из моей серии руководств по Django Celery, и вы можете найти первую здесь "Как настроить Celery с Django".

Многие новички-разработчики не знают, что Celery не будет автоматически перезагружать воркер, такой как сервер разработки Django, поэтому это может вызвать некоторые странные проблемы при последующем изучении Celery.

В этом руководстве по Django Celery я бы рассказал о том, как автоматически перезагружать работника Celery при изменении кода.

Здесь я предоставлю вам два решения этой проблемы.

Решение 1 (WatchDog)

Мы можем использовать WatchDog, чтобы контролировать файлы кода и при необходимости повторно запустить команду.

Во-первых, давайте установим пакет, обратите внимание, что PyYAML и argh также должны быть установлены.

$ pip install watchdog==0.8.3
$ pip install PyYAML==3.12
$ pip install argh==0.26.2

Предположим, вы запускаете своего работника с Celery, используя команду ниже

$ celery worker -A django_celery_example --loglevel=info

Теперь вы можете запустить команду таким образом

$ watchmedo auto-restart -d django_celery_example/ -p '*.py' -- celery worker -A django_celery_example --loglevel=info
  1. -d django_celery_example сказал watchmedo смотреть файлы в каталоге django_celery_example

  2. -p '*.py' сказал watchmedo только смотреть файлы py (поэтому, если вы измените файлы js или scss, worker не перезапустится)

Еще я хочу сказать, что если вы дважды нажмете Ctrl + C, чтобы завершить указанную выше команду, иногда дочерний процесс рабочего Celery не будет закрыт, в некоторых случаях это может вызвать некоторые странные проблемы.

Поэтому я предпочитаю метод ниже. Давайте продолжим читать, как это работает.

Решение 2 (автоматическая перезагрузка Django)

Как вы знаете, если вы измените файлы в проекте Djnago, сервер разработки перезагрузится, потому что Django поддерживает автоматическую перезагрузку.

Итак, здесь я покажу вам, как использовать код автозагрузки Django, чтобы помочь нам решить эту проблему.

Сначала создадим команду Django

.
├── db.sqlite3
├── django_celery_example
│   ├── __init__.py
│   ├── celery.py
│   ├── management
│   │   ├── __init__.py
│   │   └── commands
│   │       ├── __init__.py
│   │       └── celery_worker.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── polls
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
└── requirements.txt

Как видите, я создал команду Django celery_worker

import shlex
import subprocess

from django.core.management.base import BaseCommand
from django.utils import autoreload


def restart_celery():
    cmd = 'pkill -f "celery worker"'
    subprocess.call(shlex.split(cmd))
    cmd = 'celery worker -A django_celery_example --loglevel=info'
    subprocess.call(shlex.split(cmd))


class Command(BaseCommand):

    def handle(self, *args, **options):
        print('Starting celery worker with autoreload...')

        # For Django>=2.2
        autoreload.run_with_reloader(restart_celery)

        # For django<2.1
        # autoreload.main(restart_celery)

Здесь мы используем функцию Django autlreload для запуска Celery worker за нас, что очень чисто и просто.

Заключение

В этом руководстве по Django Celery предложено 2 способа решить проблему автозагрузки Celery worker.

Вернуться на верх