Почему 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.
На приборной панели цветов мы видим рабочего:
Также брокер:
Но в списке нет ни одной задачи, даже если она указана в журналах цветов:
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