异步任务队列Celery在Django中的使用方法


Posted in Python onJune 07, 2018

前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务。在同事的指引下接触了Celery这个异步任务队列框架,鉴于网上关于Celery和Django结合的文档较少,大部分也只是粗粗介绍了大概的流程,在实践过程中还是遇到了不少坑,希望记录下来帮助有需要的朋友。

一、Django中的异步请求

Django Web中从一个http请求发起,到获得响应返回html页面的流程大致如下:http请求发起 -- http handling(request解析) -- url mapping(url正则匹配找到对应的View) -- 在View中进行逻辑的处理、数据计算(包括调用Model类进行数据库的增删改查)--将数据推送到template,返回对应的template/response。

异步任务队列Celery在Django中的使用方法

图1. Django架构总览

同步请求:所有逻辑处理、数据计算任务在View中处理完毕后返回response。在View处理任务时用户处于等待状态,直到页面返回结果。

异步请求:View中先返回response,再在后台处理任务。用户无需等待,可以继续浏览网站。当任务处理完成时,我们可以再告知用户。

二、关于Celery

Celery是基于Python开发的一个分布式任务队列框架,支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度。

异步任务队列Celery在Django中的使用方法

图2. Celery架构

图2展示的是Celery的架构,它采用典型的生产生-消费者模式,主要由三部分组成:broker(消息队列)、workers(消费者:处理任务)、backend(存储结果)。实际应用中,用户从Web前端发起一个请求,我们只需要将请求所要处理的任务丢入任务队列broker中,由空闲的worker去处理任务即可,处理的结果会暂存在后台数据库backend中。我们可以在一台机器或多台机器上同时起多个worker进程来实现分布式地并行处理任务。

三、Django中Celery的实现

在实际使用过程中,发现在Celery在Django里的实现与其在一般.py文件中的实现还是有很大差别,Django有其特定的使用Celery的方式。这里着重介绍Celery在Django中的实现方法,简单介绍与其在一般.py文件中实现方式的差别。

1. 建立消息队列

首先,我们必须拥有一个broker消息队列用于发送和接收消息。Celery官网给出了多个broker的备选方案:RabbitMQ、Redis、Database(不推荐)以及其他的消息中间件。在官网的强力推荐下,我们就使用RabbitMQ作为我们的消息中间人。在Linux上安装的方式如下:

sudo apt-get install rabbitmq-server

命令执行成功后,rabbitmq-server就已经安装好并运行在后台了。

另外也可以通过命令rabbitmq-server来启动rabbitmq server以及命令rabbitmqctl stop来停止server。

更多的命令可以参考rabbitmq官网的用户手册:https://www.rabbitmq.com/manpages.html

2. 安装django-celery

pip install celery
pip install django-celery

3. 配置settings.py

首先,在Django工程的settings.py文件中加入如下配置代码:

import djcelery
djcelery.setup_loader()
BROKER_URL= 'amqp://guest@localhost//'
CELERY_RESULT_BACKEND = 'amqp://guest@localhost//'

其中,当djcelery.setup_loader()运行时,Celery便会去查看INSTALLD_APPS下包含的所有app目录中的tasks.py文件,找到标记为task的方法,将它们注册为celery task。BROKER_URL和CELERY_RESULT_BACKEND分别指代你的Broker的代理地址以及Backend(result store)数据存储地址。在Django中如果没有设置backend,会使用其默认的后台数据库用来存储数据。注意,此处backend的设置是通过关键字CELERY_RESULT_BACKEND来配置,与一般的.py文件中实现celery的backend设置方式有所不同。一般的.py中是直接通过设置backend关键字来配置,如下所示:

app = Celery('tasks', backend='amqp://guest@localhost//', broker='amqp://guest@localhost//')

然后,在INSTALLED_APPS中加入djcelery:

INSTALLED_APPS = (
  ……  
  'qv',
  'djcelery'
  ……  
)

4. 在要使用该任务队列的app根目录下(比如qv),建立tasks.py,比如:

异步任务队列Celery在Django中的使用方法

在tasks.py中我们就可以编码实现我们需要执行的任务逻辑,在开始处import task,然后在要执行的任务方法开头用上装饰器@task。需要注意的是,与一般的.py中实现celery不同,tasks.py必须建在各app的根目录下,且不能随意命名。

5. 生产任务

在需要执行该任务的View中,通过build_job.delay的方式来创建任务,并送入消息队列。比如:

异步任务队列Celery在Django中的使用方法

6. 启动worker的命令

#先启动服务器
python manage.py runserver
#再启动worker 
python manage.py celery worker -c 4 --loglevel=info

四、补充

Django下要查看其他celery的命令,包括参数配置、启动多worker进程的方式都可以通过python manage.py celery --help来查看:

异步任务队列Celery在Django中的使用方法

另外,Celery提供了一个工具flower,将各个任务的执行情况、各个worker的健康状态进行监控并以可视化的方式展现,如下图所示:

异步任务队列Celery在Django中的使用方法

Django下实现的方式如下: 

1. 安装flower:

pip install flower

2. 启动flower(默认会启动一个webserver,端口为5555):

python manage.py celery flower

3. 进入http://localhost:5555即可查看。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python ZipFile模块详解
Nov 01 Python
Python中使用item()方法遍历字典的例子
Aug 26 Python
python用10行代码实现对黄色图片的检测功能
Aug 10 Python
python: line=f.readlines()消除line中\n的方法
Mar 19 Python
python 通过xml获取测试节点和属性的实例
Mar 31 Python
Python中的单继承与多继承实例分析
May 10 Python
Python中logging.NullHandler 的使用教程
Nov 29 Python
python3+opencv3识别图片中的物体并截取的方法
Dec 05 Python
Python自动发送邮件的方法实例总结
Dec 08 Python
Python流行ORM框架sqlalchemy安装与使用教程
Jun 04 Python
Python如何合并多个字典或映射
Jul 24 Python
Python破解极验滑动验证码详细步骤
May 21 Python
浅谈python中对于json写入txt文件的编码问题
Jun 07 #Python
Python查看微信撤回消息代码
Jun 07 #Python
spark: RDD与DataFrame之间的相互转换方法
Jun 07 #Python
Python简单实现网页内容抓取功能示例
Jun 07 #Python
pyspark 读取csv文件创建DataFrame的两种方法
Jun 07 #Python
redis之django-redis的简单缓存使用
Jun 07 #Python
PHP实现发送和接收JSON请求
Jun 07 #Python
You might like
php preg_match_all结合str_replace替换内容中所有img
2008/10/11 PHP
有道搜索和IP138的IP的API接口(PHP应用)
2012/11/29 PHP
CI框架源码解读之利用Hook.php文件完成功能扩展的方法
2016/05/18 PHP
根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
2007/02/22 Javascript
jQuery Selector选择器小结
2010/05/06 Javascript
javascript密码强度校验代码(两种方法)
2015/08/10 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
详解如何在react中搭建d3力导向图
2018/01/12 Javascript
如何从零开始利用js手写一个Promise库详解
2018/04/19 Javascript
vue单页开发父子组件传值思路详解
2018/05/18 Javascript
详解小程序输入框闪烁及重影BUG解决方案
2018/08/31 Javascript
微信小程序云开发使用方法新手初体验
2019/05/16 Javascript
layui问题之渲染数据表格时,仅出现10条数据的解决方法
2019/09/12 Javascript
vue 虚拟DOM的原理
2020/10/03 Javascript
Python2和Python3中print的用法示例总结
2017/10/25 Python
怎么使用pipenv管理你的python项目
2018/03/12 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
Python将一个Excel拆分为多个Excel
2018/11/07 Python
不到20行代码用Python做一个智能聊天机器人
2019/04/19 Python
Django实现基于类的分页功能
2019/10/31 Python
python 模拟登陆163邮箱
2020/12/15 Python
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
北美最大的手工艺品零售商之一:Michaels Stores
2019/02/27 全球购物
Ego Shoes官网:英国时髦鞋类品牌
2020/10/19 全球购物
美国小蜜蜂Burt’s Bees德国官网:天然唇部、皮肤和身体护理产品
2020/06/14 全球购物
Smilodox官方运动服装店:从运动服到健身配件
2020/08/27 全球购物
环境工程求职简历的自我评价范文
2013/10/24 职场文书
园林设计师自荐信
2013/11/18 职场文书
通信研究生自荐信
2014/02/01 职场文书
军训 自我鉴定
2014/02/03 职场文书
超市重阳节活动方案
2014/02/10 职场文书
酒店开业策划方案
2014/06/02 职场文书
2014广电局实施党的群众路线教育实践活动方案思想汇报
2014/09/22 职场文书
常住证明范本
2015/06/23 职场文书
React Native项目框架搭建的一些心得体会
2021/05/28 Javascript
javascript中Set、Map、WeakSet、WeakMap区别
2022/12/24 Javascript