配置Celery时,需将Celery配置文件celery.py与Django设置文件settings.py放在同一目录,并在包初始化文件__init__.py中导入应用app。使用Redis作为消息代理和结果后端存储。在Windows系统上,必须安装eventlet库,并以-Peventlet参数启动Celery工作进程,否则任务将无法执行,导致队列堵塞。
其他项目需要的安装包,根据自己情况自行安装就好。
先来看 celery.py 文件内容:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings
# 设置Django的settings模块
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'testplatform.settings')
app = Celery('testplatform')
# 使用Django的settings文件来配置Celery
app.config_from_object('django.conf:settings', namespace = 'CELERY')
# 自动从所有已注册的Django app中加载任务
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
@app.task(bind = True)
def debug_task(self):
print(f'Request: {self.request!r}')
这段代码网上到处都能抄到,没什么好说的。但接下来的几个坑,才是真正让人头大的地方。
坑一:
celery.py 文件必须放在和 settings.py 同一级目录下,千万别放到项目最外层的根目录。如果放错了位置,会出现以下问题:
celery.py,那么导入 from celery import Celery 时,会和自己写的文件冲突,直接报错。celeryConfig.py(内容不变),虽然不冲突了,但后续启动服务时又会冒出各种莫名其妙的问题,让人崩溃。坑二:
与 celery.py 同级的 __init__.py 文件中,必须引入 app(也就是 Celery 创建的实例):
from .celery import app
如果不写这行,后面在视图函数里就没法用 @shared_task 装饰器,只能用 @app.task。而 @shared_task 本质上就是 @app.task 的一个快捷方式,但少了这步,它就是死活不认,实在让人摸不着头脑。
接下来是 settings.py 里的坑。
坑一:broker 和 result backend 的配置
刚开始问文心一言,它告诉我 CELERY_RESULT_BACKEND="django-celery-results",结果启动就失败了。后来又改成 CELERY_RESULT_BACKEND="django-db",虽然能启动,但任务根本不执行。最后走了一圈弯路发现,最稳妥的做法是把任务队列和结果队列都指向 Redis:
CELERY_BROKER_URL = f'redis://:{REDIS_PW}@{REDIS_IP}:{REDIS_PORT}/0' # Redis数据库地址
CELERY_RESULT_BACKEND = f'redis://:{REDIS_PW}@{REDIS_IP}:{REDIS_PORT}/1'
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Asia/Shanghai' # 根据需要调整时区
CELERY_BROKER_CONNECTION_RETRY_ON_STARTUP = True
坑二:INSTALLED_APPS 里的 django_celery_results
在排雷过程中,发现网上有人建议在 INSTALLED_APPS 中加入 "django_celery_results"。我试了一下,发现不写也完全没影响,根本用不上。所以这里可以不用加:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
# 'django_celery_results' # 可不加
]
视图函数和异步任务本身没什么好讲的,网上都有现成的例子。这里贴一下我练习时用的代码:
@csrf_exempt
def reset_data_api(request):
# 调用异步任务
result = reset_data.delay()
task_id = result.task_id
return JsonResponse({'status': True, 'data': {'message': '任务开始执行', 'task_id': f'{task_id}'}})
@shared_task
def reset_data():
logger.info('开始执行任务')
result = {
"a": 123,
"b": 456
}
logger.info('结束执行任务')
return result
遇到最大的坑!!!!
很难想象,Celery 服务启动正常,任务消息也能收到,Redis 服务也是正常的,没有任何报错信息,但异步任务就是不执行,存放结果的队列里始终没有数据。搞了大半天,觉都睡不好,就是想不明白。
问文心一言,完全找不到原因,各种排查。最后在百度上搜到,才发现问题所在:
Celery 在 Windows 下运行有坑,需要借助 gevent、eventlet 等才能实现正常功能。解决方案是:
先 pip 安装 eventlet,然后运行 celery 时加上 -P eventlet 参数就行了。


基本上就这些了,后面使用过程中如果还有新坑,再继续补充~~
以上是个人在实战中遇到的真实问题,希望能给大家一个参考,少走一些弯路。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述