Celery Beat任务已执行但未注册到django_celery_beat_periodictask的问题咨询
问题描述
在Windows电脑上完成Celery Worker和Celery Beat基础功能实现后,Celery Beat已成功发送任务,Celery Worker也接收并执行了任务,但预期的django_celery_beat_periodictask表中没有注册任务。
核心问题
为何django_celery_beat_periodictask表中没有任务?
附加问题
- 若该表中无任务,Celery Beat是如何执行任务的?
- Celery Worker还会从哪些数据源获取任务?
项目信息
项目结构
celery_with_django |- django_celery_project |- __init__.py |- settings.py |- celery.py other files |- mainapp |- tasks.py other files |- requirements.txt
运行命令
# Django服务 python manage.py runserver # Celery Worker celery -A django_celery_project.celery worker --pool=solo -l info # (不加--pool=solo时终端难以中断) # Celery Beat celery -A django_celery_project beat -l info
代码内容
requirements.txt
amqp==5.1.1 asgiref==3.7.2 async-timeout==4.0.2 billiard==3.6.4.0 celery==5.2.7 click==8.1.3 click-didyoumean==0.3.0 click-plugins==1.1.1 click-repl==0.2.0 colorama==0.4.6 cron-descriptor==1.4.0 Django==4.2.1 django-celery-beat==2.5.0 django-celery-results==2.5.1 django-timezone-field==5.1 kombu==5.2.4 prompt-toolkit==3.0.38 python-crontab==2.7.1 python-dateutil==2.8.2 pytz==2023.3 redis==4.5.5 six==1.16.0 sqlparse==0.4.4 typing_extensions==4.6.3 tzdata==2023.3 vine==5.0.0 wcwidth==0.2.6
django_celery_project/init.py
from .celery import app as celery_app __all__ = ('celery_app',)
django_celery_project/settings.py
# other settings # CELERY SETTINGS CELERY_BROKER_URL = 'redis://127.0.0.1:6379' CELERY_RESULT_BACKEND = 'django-db' CELERY_ACCEPT_CONTENT = ['application/json'] CELERY_RESULT_SERIALIZER = 'json' CELERY_TASK_SERIALIZER = 'json' CELERY_TIMEZONE = 'Asia/Kolkata'
django_celery_project/celery.py
from __future__ import absolute_import, unicode_literals import os from celery import Celery from django.conf import settings from celery.schedules import crontab os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_celery_project.settings') app = Celery('django_celery_project') app.conf.enable_utc = False app.conf.update(timezone='Asia/Kolkata') app.config_from_object(settings, namespace='CELERY') app.autodiscover_tasks() @app.task(bind=True) def debug_task(self): print(f"Request: {self.request!r}") app.conf.beat_schedule = { '_test_celery_beat_schedule_': { 'task': 'mainapp.tasks.test_celery_beat_schedule', 'schedule': crontab(hour=10, minute=14), 'args': ("Hello user, ",) }, }
mainapp/tasks.py
from __future__ import absolute_import, unicode_literals from celery import shared_task import time def internal_func(): print("--> internal func") @shared_task(bind=True, name='_test_celery_worker_') def test_celery_worker(self): for i in range(10): time.sleep(2) print(i) internal_func() return "Celery worker worked" @shared_task(bind=True) def test_celery_beat_schedule(self, msg): print(msg + " the task will be executed every day!") return "Celery beat_schedular worked"
验证信息
- Celery Beat终端:已发送到期任务
- Celery Worker终端:已接收任务
django_celery_beat_periodictask表:为空
问题解答
核心问题解答
你当前是通过代码中硬编码app.conf.beat_schedule配置定时任务,这种属于Celery Beat的静态配置,任务信息直接存储在代码里,不会写入django_celery_beat_periodictask表。
django_celery_beat的数据库存储功能,需要你启用数据库调度器,并通过Django Admin或代码向数据库中添加任务,才会在该表生成记录。
附加问题解答
1. 无数据库任务时Celery Beat如何执行任务?
Celery Beat默认使用celery.beat.PersistentScheduler调度器,它会读取代码中beat_schedule的配置,将任务调度信息存储在本地的celerybeat-schedule文件中(默认在项目根目录),根据这个文件的规则触发任务,无需依赖数据库表。
2. Celery Worker的任务来源
Celery Worker获取任务的数据源主要有以下几种:
- 消息队列(Broker):核心来源,包括你配置的Redis、RabbitMQ等,Celery Beat、Django业务代码、其他服务都可向Broker发送任务;
- Celery Beat定时触发:Beat按调度规则将任务发送到Broker,Worker从Broker拉取执行;
- 手动触发任务:通过
delay()或apply_async()在代码中手动提交的任务; - 任务重试:配置了重试规则的失败任务,会重新进入Broker等待执行;
- 数据库调度任务(django_celery_beat):启用数据库调度器时,Beat从
django_celery_beat_periodictask等表读取任务并发送到Broker。
内容的提问来源于stack exchange,提问作者devesh-gupta
相关产品推荐
相关产品推荐

