Django集成Celery Beat时定时任务无法执行的问题求助
Django中Celery Beat定时任务无法触发的问题
期望每日18:47触发execute_daily_task任务并打印celery is working,但任务未执行,Celery Beat控制台始终显示“Starting...”状态。
已完成的配置与操作
1. settings.py配置
#CELERY CELERY_BROKER_URL = 'redis://localhost:6379' # Redis代理URL CELERY_RESULT_BACKEND = 'redis://localhost:6379' # Redis结果后端URL # Celery Beat(定时任务)设置 CELERY_BEAT_SCHEDULE = { 'execute_daily_task': { 'task': 'your_app.tasks.execute_daily_task', # 任务路径 'schedule': crontab(minute=47, hour=18), # 每日18:47执行 }, }
2. 根目录__init__.py配置
# 确保Django启动时始终导入应用,使shared_task使用该应用 from .celery import app as celery_app __all__ = ('celery_app',)
3. 根目录celery.py配置
# celery.py from __future__ import absolute_import, unicode_literals import os from celery import Celery # 设置DJANGO_SETTINGS_MODULE环境变量以适配Django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'sites.settings') # 创建Celery实例 app = Celery('sites') # 从Django设置加载Celery配置,命名空间为CELERY app.config_from_object('django.conf:settings', namespace='CELERY') # 自动发现并注册Django应用中的任务 app.autodiscover_tasks()
4. users应用中tasks.py定义任务
from celery import shared_task from django.core.mail import send_mail from datetime import date from .models import Company @shared_task def execute_daily_task(): print('celery is working')
5. 启动的服务及日志
- Celery Worker:执行命令
celery -A sites worker --loglevel=info,日志如下:
celery -A sites worker --loglevel=info -------------- celery@LAPTOP-2554OM7H v5.3.3 (emerald-rush) --- ***** ----- -- ******* ---- Windows-10-10.0.22621-SP0 2023-09-01 18:45:29 - *** --- * --- - ** ---------- [config] - ** ---------- .> app: sites:0x26e0ad706d0 - ** ---------- .> transport: redis://localhost:6379// - ** ---------- .> results: redis://localhost:6379/ - *** --- * --- .> concurrency: 4 (prefork) -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) --- ***** ----- -------------- [queues] .> celery exchange=celery(direct) key=celery [tasks] . users.tasks.execute_daily_task [2023-09-01 18:45:29,398: WARNING/MainProcess] C:\Users\hp\desktop\TechnicalSupport\venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine whether broker connection retries are made during startup in Celery 6.0 and above. If you wish to retain the existing behavior for retrying connections on startup, you should set broker_connection_retry_on_startup to True. warnings.warn( [2023-09-01 18:45:30,133: INFO/MainProcess] Connected to redis://localhost:6379// [2023-09-01 18:45:30,135: WARNING/MainProcess] C:\Users\hp\desktop\TechnicalSupport\venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: The broker_connection_retry configuration setting will no longer determine whether broker connection retries are made during startup in Celery 6.0 and above. If you wish to retain the existing behavior for retrying connections on startup, you should set broker_connection_retry_on_startup to True. warnings.warn( [2023-09-01 18:45:30,228: INFO/MainProcess] mingle: searching for neighbors [2023-09-01 18:45:30,398: INFO/SpawnPoolWorker-1] child process 19332 calling self.run() [2023-09-01 18:45:30,457: INFO/SpawnPoolWorker-2] child process 18856 calling self.run() [2023-09-01 18:45:30,508: INFO/SpawnPoolWorker-3] child process 17284 calling self.run() [2023-09-01 18:45:30,578: INFO/SpawnPoolWorker-4] child process 19352 calling self.run() [2023-09-01 18:45:31,495: INFO/MainProcess] mingle: all alone [2023-09-01 18:45:32,769: INFO/MainProcess] celery@LAPTOP-2554OM7H ready.
- Celery Beat:执行命令
celery -A sites beat --loglevel=info,日志如下:
celery -A sites beat --loglevel=info celery beat v5.3.3 (emerald-rush) is starting. __ - ... __ - _ LocalTime -> 2023-09-01 18:45:38 Configuration -> . broker -> redis://localhost:6379// . loader -> celery.loaders.app.AppLoader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%INFO . maxinterval -> 5.00 minutes (300s) [2023-09-01 18:45:38,459: INFO/MainProcess] beat: Starting... (venv) PS C:\Users\hp\desktop\TechnicalSupport\sites> celery -A sites beat --loglevel=info celery beat v5.3.3 (emerald-rush) is starting. __ - ... __ - _ LocalTime -> 2023-09-01 18:46:05 Configuration -> . broker -> redis://localhost:6379// . loader -> celery.loaders.app.AppLoader . scheduler -> celery.beat.PersistentScheduler . db -> celerybeat-schedule . logfile -> [stderr]@%INFO . maxinterval -> 5.00 minutes (300s) [2023-09-01 18:46:05,258: INFO/MainProcess] beat: Starting...
- Django开发服务器:执行命令
python manage.py runserver,日志如下:
C:\Users\hp\Desktop\TechnicalSupport\sites\sites\settings.py changed, reloading. Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). September 01, 2023 - 18:46:01 Django version 4.2.1, using settings 'sites.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.
排查与解决步骤
1. 修正任务路径错误
在settings.py的CELERY_BEAT_SCHEDULE中,任务路径写的是your_app.tasks.execute_daily_task,但实际任务在users应用下,应改为:
'task': 'users.tasks.execute_daily_task',
2. 导入crontab依赖
settings.py中使用了crontab但未导入,需在文件顶部添加:
from celery.schedules import crontab
3. 清除Celery Beat调度文件
删除项目根目录下的celerybeat-schedule文件(该文件存储调度状态,损坏会导致任务不触发),然后重启Celery Beat服务。
4. 添加Redis连接重试配置
根据日志中的警告,在settings.py中添加:
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
避免启动时Redis连接失败导致Beat无法正常工作。
5. 验证Redis服务状态
执行redis-cli ping命令,返回PONG表示Redis服务正常运行,若未返回则启动Redis服务后重试。
6. 手动测试任务可用性
在Django Shell中手动调用任务,验证任务本身是否正常:
python manage.py shell
在Shell中执行:
from users.tasks import execute_daily_task execute_daily_task.delay()
查看Celery Worker日志是否输出celery is working,若有则任务本身正常,问题出在Beat调度环节。
7. 更换调度器(可选)
若PersistentScheduler存在问题,可尝试使用DatabaseScheduler:
- 安装依赖:
pip install django-celery-beat - 在
settings.py的INSTALLED_APPS中添加django_celery_beat - 执行迁移:
python manage.py migrate - 重启Beat时指定调度器:
celery -A sites beat --loglevel=info --scheduler django_celery_beat.schedulers:DatabaseScheduler
内容的提问来源于stack exchange,提问作者Bte Deni
相关产品推荐
相关产品推荐

