异步任务队列Celery在Django中的使用方法
作者:zni.feng 发布时间:2023-08-03 06:26:39
前段时间在Django Web平台开发中,碰到一些请求执行的任务时间较长(几分钟),为了加快用户的响应时间,因此决定采用异步任务的方式在后台执行这些任务。在同事的指引下接触了Celery这个异步任务队列框架,鉴于网上关于Celery和Django结合的文档较少,大部分也只是粗粗介绍了大概的流程,在实践过程中还是遇到了不少坑,希望记录下来帮助有需要的朋友。
一、Django中的异步请求
Django Web中从一个http请求发起,到获得响应返回html页面的流程大致如下:http请求发起 -- http handling(request解析) -- url mapping(url正则匹配找到对应的View) -- 在View中进行逻辑的处理、数据计算(包括调用Model类进行数据库的增删改查)--将数据推送到template,返回对应的template/response。
图1. Django架构总览
同步请求:所有逻辑处理、数据计算任务在View中处理完毕后返回response。在View处理任务时用户处于等待状态,直到页面返回结果。
异步请求:View中先返回response,再在后台处理任务。用户无需等待,可以继续浏览网站。当任务处理完成时,我们可以再告知用户。
二、关于Celery
Celery是基于Python开发的一个分布式任务队列框架,支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度。
图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,比如:
在tasks.py中我们就可以编码实现我们需要执行的任务逻辑,在开始处import task,然后在要执行的任务方法开头用上装饰器@task。需要注意的是,与一般的.py中实现celery不同,tasks.py必须建在各app的根目录下,且不能随意命名。
5. 生产任务
在需要执行该任务的View中,通过build_job.delay的方式来创建任务,并送入消息队列。比如:
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提供了一个工具flower,将各个任务的执行情况、各个worker的健康状态进行监控并以可视化的方式展现,如下图所示:
Django下实现的方式如下:
1. 安装flower:
pip install flower
2. 启动flower(默认会启动一个webserver,端口为5555):
python manage.py celery flower
3. 进入http://localhost:5555即可查看。
来源:https://www.cnblogs.com/znicy/p/5626040.html


猜你喜欢
- 1.介绍PDF 格式是与平台无关,它独立于底层操作系统和渲染引擎。事实上,PDF 是基于一种脚本语言—&mdas
- 比如有文章表 Article(Id,Category,InsertDate),现在要用SQL找出每种类型中时间最新的前N个数据组成的集合,一
- proxytable代理根路径的同时增加其他代理Vue 项目有一个需求,需要对根路径 ‘/’ 进行代
- function getElementsByClassName(elem_name,elem_tags) { //elem_name:查询的
- 在Transact-SQL语句中,我们主要使用OpenDataSource函数、OPENROWSET 函数,关于函数的详细说明,请参考SQL
- 本文实例讲述了Python3中正则模块re.compile、re.match及re.search函数用法。分享给大家供大家参考,具体如下:r
- 一、项目视图分析通过上图,我们可以看到,一个完整的项目,基本包括三个部分:用户视图层、接口层、数据处理层,其中,用户视图层是用来接收用户的数
- 初始化并封装在main.js中对bus进行初始化, Bus是一个不具备 DOM 的组件,它具有的仅仅只是它实例方法Vue.prototype
- 1.确保系统中有依赖的libaio 软件,如果没有: yum -y
- 如下所示:#!/usr/bin/env pythonimport osimport sysclass CConsole: M_MAP_COL
- 详解Python MD5加密Python 3下MD5加密# 由于MD5模块在python3中被移除# 在python3中使用hashlib模
- 当今互联网时代,数据处理已经成为了一个非常重要的任务。而MySQL作为一款开源的关系型数据库,被广泛应用于各种场景。本篇博客将介绍如何使用P
- 跟着趣味开发python一起实现的弹球小游戏游戏运行效果实现流程1.创建游戏画布(创建ball类)2.增加几个动作(让小球移动、让小球来回反
- 本人在CentOS6.4上安装万mysql后,无法通过root进入,因为安装的时候,并没有设置root密码,似乎有个初始随机密码,但是不记得
- 前言本文仅仅介绍了常见的一些JS加密,并记录了JS和Python的实现方式常见的加密算法基本分为这几类:(1)base64编码伪加密(2)线
- 一、python下载安装下载安装python最新版本https://www.python.org/downloads/windows/这里勾
- Python input()函数Python input()函数教程在 Python 中,input() 函数用于获取用于的输入,并给出提示
- 1、Python 条件语句Python 条件语句是通过一条或多条语句的执行结果来决定执行的代码块。Python 编程中 if 语句用于控制程
- 在程序的开发过程中,处理分页是大家接触比较频繁的事件,因为现在软件基本上都是与数据库进行挂钩的。但效率又是我们所追求的,如果是像原来那样把所
- 在昨天的文章,《 block 和 inline 的区别是?》里,我给大家留了个问题——LI 元素到底是block level 的,还是 in