django集成celery
Celery是一个基于分布式消息传递的开源异步任务队列,在django实际应用场景下,往往有一些较为耗时,但并不需要返回值的任务,
例如发送邮件,更新我们自己的统计数据库,这时我们可以将这些任务交由celery管理,以加快网页返回。
本文重点来讲解django+redis+celery的配置,为什么这么配置自行google,例如absolute_import的用处等,另外也可查看官方给出的django-celery配置实例。
django项目布局如下:
1 2 3 4 5 6 7 | proj ├── proj │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py |
1. 新建proj/proj/celery.py文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import os from celery import Celery from django.conf import settings # set the default Django settings module for the 'celery' program. os.environ.setdefault( 'DJANGO_SETTINGS_MODULE' , 'proj.settings' ) app = Celery( 'proj' ) # Using a string here means the worker will not have to # pickle the object when using Windows. app.config_from_object( 'django.conf:settings' ) app.autodiscover_tasks( lambda : settings.INSTALLED_APPS) @app .task(bind = True ) def debug_task( self ): print ( 'Request: {0!r}' . format ( self .request)) |
2. 在proj/proj/__init__.py 模块中导入这个 Celery 实例,以确保当 Django 启动时可以加载这个 app
并且 @shared_task 装饰器也能使用。
1 2 3 | from .celery import app as celery_app __all__ = [ 'celery_app' ] |
3. settings.py配置
1 2 3 4 5 6 7 8 9 | # celery settings # Broker BROKER_URL = 'redis://127.0.0.1:6379/1' # Result # CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1' CELERY_ACCEPT_CONTENT = [ 'json' ] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' |
4. 在各app下创建tasks.py文件,注意此处只能以tasks命名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from celery import shared_task @shared_task def add(x, y): return x + y # pv uv 统计案例 from django.db.models import F # 获取源数据 from .models import Post @app .task def increase_pv(post_id): return Post.objects. filter ( id = post_id).update(pv = F( 'pv' ) + 1 ) |
5. views.py中引入即可
1 2 3 4 | from .tasks import add add.delay( * args) |
6. 启动Worker
在django项目根路径下,键入
1 | $ celery worker - A proj - l info |
-------------------------------------
bug 记录,真实环境centos部署没有问题。
环境 win10,celery==4.3.0,redis==3.2.1(celery版本要求redis>3.2.0)
启动worker成功,但执行异步任务失败
报ValueError: not enough values to unpack (expected 3, got 0)
解决方式
1 2 3 | $ pip install eventlet $celery worker - A proj - l info - P eventlet |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步