Celery+Redis多文件任务无法加载问题求助
解决Celery无法加载外部文件任务的问题
这是Celery新手常遇到的典型问题——默认情况下,Celery只会识别与Celery实例同文件中注册的任务,不会自动遍历所有子目录的tasks.py文件。针对你的项目结构,这里有几种优雅的解决方式:
方法一:使用Celery自动任务发现功能
Celery内置了autodiscover_tasks()方法,能自动扫描指定包下的tasks.py文件并完成任务注册。修改你的celery_app.py:
from __future__ import absolute_import from celery import Celery celery_application = Celery('celery_test', backend='redis://localhost', broker='redis://localhost') # 自动扫描指定子包下的tasks.py celery_application.autodiscover_tasks(['celery_tasks.async', 'celery_tasks.marker']) @celery_application.task def test_celery(): print(4)
如果想一次性扫描celery_tasks下所有子包的tasks.py,可以直接传入父包路径,更灵活:
celery_application.autodiscover_tasks(['celery_tasks'])
这样启动worker时,Celery会自动找到async/tasks.py和marker/tasks.py里的任务。
方法二:在父包__init__.py中手动导入任务模块
另一种方式是在celery_tasks/__init__.py中导入所有任务模块,这样当Celery加载celery_app时,会连带加载这些模块,任务自然就完成注册了:
修改celery_tasks/__init__.py:
from __future__ import absolute_import # 导入所有任务模块 from .async import tasks as async_tasks from .marker import tasks as marker_tasks
这种方式不需要修改celery_app.py,但后续新增任务目录时,需要手动补充导入语句。
方法三:启动命令中指定任务模块(不推荐,任务多了繁琐)
如果只是临时测试,可以在启动worker时通过--include参数指定任务模块:
celery --app=celery_tasks.celery_app:celery_application worker -l debug --include=celery_tasks.async.tasks,celery_tasks.marker.tasks
但这种方式在任务数量多的时候会非常麻烦,所以更推荐前两种方法。
为什么之前的方式不行?
Celery的任务注册依赖@celery_application.task装饰器,只有当包含这个装饰器的模块被导入时,任务才会被注册到Celery实例中。你之前启动worker时只加载了celery_app.py,其他tasks.py模块没有被导入,所以任务没被识别。
内容的提问来源于stack exchange,提问作者fferrin
相关产品推荐
相关产品推荐

