Celery无法自动加载Django项目中config应用的任务问题咨询
在我的Django项目中,Celery的autodiscover_tasks功能原本能正常加载所有应用的tasks.py文件,但最近发现config应用下的tasks.py中的任务不再被加载,其他应用的任务都能正常识别。
我已经尝试过这些操作但都无效:
- 在Shell中手动执行
from config.tasks import *没有报错,且能手动运行该应用下的任务 - 在
autodiscover_tasks中添加force=True参数
项目结构
-config --apps.py --views.py --models.py --tasks.py -monitoring --apps.py --views.py --models.py --tasks.py -app --apps.py --settings.py --celery.py
celery.py配置
from __future__ import absolute_import, unicode_literals import os, django from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'app.settings') django.setup() # This is key app = Celery("app") app.config_from_object('django.conf:settings', namespace='CELERY') # Load task modules from all registered Django app configs. app.autodiscover_tasks() if __name__ == '__main__': app.start()
settings.py相关配置
CELERY_TIMEZONE = 'Europe/London' ENABLE_UTC = True CELERY_BROKER_URL = 'redis://redis:6379' CELERY_RESULT_BACKEND = 'redis://redis:6379' CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler' CELERY_TASK_TIME_LIMIT = 540 INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', 'haystack', 'django_tables2', 'django_filters', 'django_celery_beat', 'config.apps.ConfigConfig', 'monitoring.apps.MonitoringConfig', 'storages', 'stdimage', 'simple_history', 'crispy_forms', 'rest_framework', 'rest_framework.authtoken', )
config应用tasks.py片段
from __future__ import absolute_import, unicode_literals import requests, re, json, ipaddress, time, meraki, logging, random, gzip, diffios from celery import chord, group from app.celery import app from django.conf import settings from config.models import * @app.task def execute_command(device_id, cmd, user_id): ... return output
Celery控制台输出
celery_1 | -------------- celery@3504f0d9bb2e v4.3.1 (rhubarb) celery_1 | ---- **** ----- celery_1 | --- * *** * -- Linux-4.19.121-linuxkit-x86_64-with-debian-9.7 2021-02-09 12:14:41 celery_1 | -- * - **** --- celery_1 | - ** ---------- [config] celery_1 | - ** ---------- .> app: app:0x7f82527f04a8 celery_1 | - ** ---------- .> transport: redis://redis:6379// celery_1 | - ** ---------- .> results: redis://redis:6379/ celery_1 | - *** --- * --- .> concurrency: 30 (prefork) celery_1 | -- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) celery_1 | --- ***** ----- celery_1 | -------------- [queues] celery_1 | .> celery exchange=celery(direct) key=celery celery_1 | celery_1 | celery_1 | [tasks] celery_1 | . app_settings.tasks.import_meraki_templates celery_1 | . celery.accumulate celery_1 | . celery.backend_cleanup celery_1 | . celery.chain celery_1 | . celery.chord celery_1 | . celery.chord_unlock celery_1 | . celery.chunks celery_1 | . celery.group celery_1 | . celery.map celery_1 | . celery.starmap celery_1 | . app.celery.debug_task celery_1 | . monitoring.tasks.link_checks celery_1 | . monitoring.tasks.service_checks
给你几个具体的排查思路,按顺序试试应该能找到问题:
先检查config应用的apps.py配置
确认ConfigConfig类的name属性是不是准确设置为'config'——Celery的自动发现是靠Django应用配置的name来定位任务文件的。正确的config/apps.py应该是这样:from django.apps import AppConfig class ConfigConfig(AppConfig): name = 'config' verbose_name = 'Config'如果
name写成了'config.apps'这类错误值,Celery肯定找不到对应的tasks.py。手动指定任务发现的应用列表
在celery.py里,把app.autodiscover_tasks()改成手动指定应用:app.autodiscover_tasks(['config', 'monitoring'])如果这样能加载到config的任务,说明自动发现逻辑没正确识别INSTALLED_APPS里的config应用,大概率是应用配置的问题。
排查tasks.py里的循环依赖
虽然你手动导入没问题,但Celery自动发现时的导入环境可能不一样。看看config/tasks.py里的导入有没有循环依赖——比如config/models.py是不是反过来导入了tasks里的内容?这种情况会导致Celery自动加载失败,但手动导入时可能不会触发报错。清理缓存并重启Celery
Celery有时候会缓存任务列表,哪怕你改了配置也不更新。试试这些步骤:- 彻底停掉Celery worker和beat进程
- 清理Redis里的Celery相关缓存(如果Redis还有其他重要数据,就别用
FLUSHDB,可以针对性删除Celery的键) - 用
--purge参数重启worker,清除旧的任务队列:celery -A app worker --purge -l info
开启调试日志看加载细节
启动Celery worker时用-l debug开启详细日志,看看日志里有没有加载config任务时的错误信息:celery -A app worker -l debug日志里可能会明确告诉你为什么没加载到config的tasks.py,比如导入错误、文件权限问题之类的。
验证Django应用是否被正确注册
在Django shell里执行下面的命令,确认config应用有没有被正确加载:from django.apps import apps print(apps.get_app_config('config'))如果报错找不到应用,说明INSTALLED_APPS里的
config.apps.ConfigConfig路径或者类名写错了。
内容的提问来源于stack exchange,提问作者AlexW

