Почему Celery не выполняет задачи, запланированные в результате выполнения сигнала @worker_ready?

У меня есть докеризованное приложение, в котором запущены Django (Gunicorn) и Celery (как рабочий, так и beat - django_celery_beat - по одному в каждом контейнере), с Redis, Nginx и Postgres.

Процесс celery запускается после того, как django heathcheck возвращает OK, чтобы дождаться всех шагов, необходимых для запуска django (миграция, фиксация, добавление пользователей, сбор статики и т.д.).

Мне нужно планировать задачи в соответствии с данными, хранящимися в моей модели, при каждом запуске приложения. Для этого я использую сигнал worker_ready.

Запланированные задачи сохраняются в таблицах django_celery_beat, но ни одна задача не выполняется, как ожидалось.

docker-compose.yml

services:
  redis:
    container_name: redis
    image: redis:latest
    restart: unless-stopped
    networks:
      - redisnet
  postgres:
    container_name: postgres
    image: postgres:latest
    env_file:
      - ./.env
    environment:
      POSTGRES_USER: ${LOCALDEV_POSTGRES_USER:-postgres}
      POSTGRES_PASSWORD: ${LOCALDEV_POSTGRES_PASSWORD:-changeme}
      POSTGRES_DB: ${LOCALDEV_POSTGRES_DB:-db}
    volumes:
      - pgdata:/var/lib/postgresql/pgdata
    ports:
      - 5432:5432
    networks:
      - postgresnet
    restart: unless-stopped
  django:
    container_name: django
    build:
      dockerfile: Dockerfile
    command: /home/app/web/django-entrypoint.sh
    volumes:
      - static_volume:/home/app/web/static
    expose:
      - 8000
    env_file:
      - ./.env
    networks:
      - postgresnet
      - redisnet
      - webnet
    depends_on:
      - redis
      - postgres
  celery_worker:
    container_name: celery_worker
    build:
      dockerfile: Dockerfile
    command: /home/app/web/worker-entrypoint.sh
    env_file:
      - ./.env
    networks:
      - postgresnet
      - redisnet
      - webnet
    depends_on:
      - redis
      - postgres
      - django
  celery_beat:
    container_name: celery_beat
    build:
      dockerfile: Dockerfile
    command: /home/app/web/beat-entrypoint.sh
    env_file:
      - ./.env
    networks:
      - postgresnet
      - redisnet
      - webnet
    depends_on:
      - redis
      - postgres
      - django
  celery_flower:
    container_name: celery_flower
    build:
      dockerfile: Dockerfile
    command: /home/app/web/flower-entrypoint.sh
    expose:
      - 5555
    env_file:
      - ./.env
    networks:
      - redisnet
      - webnet
    depends_on:
      - redis
  nginx:
    container_name: nginx
    build: ./nginx
    volumes:
      - static_volume:/home/app/web/static
    ports:
      - 80:80
    depends_on:
      - django
      - celery_worker
      - celery_beat
    networks:
      - webnet

volumes:
  static_volume:
  pgdata:

networks:
  postgresnet:
  redisnet:
  webnet:

Точки входа:

  • Джанго: gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers=1
  • celery worker: celery -A core worker --loglevel="$LOG_LEVEL"
  • celery beat: celery -A core beat --loglevel="$LOG_LEVEL"
  • celery flower: celery -A core flower --loglevel="$LOG_LEVEL"

core.settings.py

(...)

INSTALLED_APPS = [
    ...
    'django_celery_beat',
    ...
]

(...)

CELERY_TIMEZONE = TIME_ZONE
CELERY_BROKER_URL = 'redis://{}:6379/0'.format(env('DJANGO_REDIS_HOST'))
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
CELERY_TASK_TIME_LIMIT = 30 * 60
CELERY_RESULT_BACKEND = 'redis://{}:6379/0'.format(env('DJANGO_REDIS_HOST'))

core.celery.py

import os

from celery import Celery
from celery.signals import setup_logging

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')

app = Celery('core')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.conf.broker_connection_retry_on_startup = True

app.autodiscover_tasks()

@setup_logging.connect
def config_loggers(*args, **kwargs):
    from logging.config import dictConfig  # noqa
    from django.conf import settings  # noqa
    dictConfig(settings.LOGGING)

@app.task(bind=True, ignore_result=True)
def debug_task(self) -> None:
    print(f'Request: {self.request!r}')

core.__init__.py

from .celery import app as celery_app

__all__ = ('celery_app',)

engine.tasks.py

Задачи schedule_sistema_run_interval и schedule_clocked вызываются в результате выполнения задачи setup, используя функцию delay().

В журналах ошибок нет.

Журналы рабочего сельдерея:

Целери бьют поленья:

Версии:

  • Python 3.12
  • Django 5.0.6
  • Celery 5.4.0
  • django-celery-beat 2.6.0
  • Flower 2.0.1

Только для тестов я установил, чтобы запланированные задачи (как по часам, так и по интервалу) запускались через 1 минуту.

Я уже пытался изменить аннотацию задач с shared_task на app.task, но никаких изменений в поведении не произошло.

Я попытался запустить celery worker и beat в одном и том же процессе. Я также изменил сигнал worker_ready на beat_init. Решение не было найдено.

Я проверил в каждом контейнере celery, что оба они правильно указывают на контейнер redis.

На приборной панели цветов мы видим рабочего:

enter image description here

Также брокер:

enter image description here

Но в списке нет ни одной задачи, даже если она указана в журналах цветов:

2024-05-29 15:15:39 [I 240529 15:15:39 command:177] Registered tasks: 
2024-05-29 15:15:39     ['celery.accumulate',
2024-05-29 15:15:39      'celery.backend_cleanup',
2024-05-29 15:15:39      'celery.chain',
2024-05-29 15:15:39      'celery.chord',
2024-05-29 15:15:39      'celery.chord_unlock',
2024-05-29 15:15:39      'celery.chunks',
2024-05-29 15:15:39      'celery.group',
2024-05-29 15:15:39      'celery.map',
2024-05-29 15:15:39      'celery.starmap',
2024-05-29 15:15:39      'core.celery.debug_task',
2024-05-29 15:15:39      'engine.tasks.execute_from_module',
2024-05-29 15:15:39      'engine.tasks.message_received',
2024-05-29 15:15:39      'engine.tasks.run_sistema_addon_interval',
2024-05-29 15:15:39      'engine.tasks.schedule_clocked',
2024-05-29 15:15:39      'engine.tasks.schedule_sistema_run_interval',
2024-05-29 15:15:39      'engine.tasks.setup']
2024-05-29 15:15:39 [I 240529 15:15:39 mixins:228] Connected to redis://redis:6379/0

enter image description here

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