Django使用Celery异步任务队列的使用


Posted in Python onMarch 13, 2018

1 Celery简介

Celery是异步任务队列,可以独立于主进程运行,在主进程退出后,也不影响队列中的任务执行。

任务执行异常退出,重新启动后,会继续执行队列中的其他任务,同时可以缓存停止期间接收的工作任务,这个功能依赖于消息队列(MQ、Redis)。

1.1 Celery原理

Django使用Celery异步任务队列的使用

Celery的 架构 由三部分组成,消息中间件(message broker),任务执行单元(worker)和任务执行结果存储(task result store)组成。

消息中间件:Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括, RabbitMQRedis ,  MongoDB  (experimental), Amazon SQS (experimental),CouchDB (experimental), SQLAlchemy (experimental),Django ORM (experimental), IronMQ。推荐使用:RabbitMQ、Redis作为消息队列。

任务执行单元:Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。

任务结果存储:Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, Redis,memcached, MongoDB,SQLAlchemy, Django ORM,Apache Cassandra, IronCache

1.2Celery适用场景

异步任务处理:例如给注册用户发送短消息或者确认邮件任务。 大型任务:执行时间较长的任务,例如视频和图片处理,添加水印和转码等,需要执行任务时间长。 定时执行的任务:支持任务的定时执行和设定时间执行。例如性能压测定时执行。

 2Celery开发环境准备

 2.1 环境准备

软件名称 版本号 说明
Linux Centos 6.5(64bit) 操作系统
Python 3.5.2
Django 1.10 Web框架
Celery 4.0.2 异步任务队列
Redis 2.4 消息队列

2.2     Celery安装

使用方法介绍:

Celery的运行依赖消息队列,使用时需要安装redis或者rabbit。

这里我们使用Redis。安装redis库:

sudo yum install redis

启动redis:

sudo service redis start

安装celery库

sudo pip install celery==4.0.2

3Celery单独执行任务

 3.1编写任务

创建task.py文件

说明:这里初始Celery实例时就加载了配置,使用的redis作为消息队列和存储任务结果。

Django使用Celery异步任务队列的使用

运行celery:

$ celery -A task worker --loglevel=info

看到下面的打印,说明celery成功运行。

Django使用Celery异步任务队列的使用

3.2 调用任务

直接打开python交互命令行

执行下面代码:

Django使用Celery异步任务队列的使用

可以celery的窗口看到任务的执行信息

Django使用Celery异步任务队列的使用

任务执行状态监控和获取结果:

Django使用Celery异步任务队列的使用

3.3任务调用方法总结

有两种方法:

delay和apply_async ,delay方法是apply_async简化版。

add.delay(2, 2)
add.apply_async((2, 2))
add.apply_async((2, 2), queue='lopri')

delay方法是apply_async简化版本。

apply_async方法是可以带非常多的配置参数,包括指定队列等

Queue 指定队列名称,可以把不同任务分配到不同的队列 3.4     任务状态

每个任务有三种状态:PENDING -> STARTED -> SUCCESS

任务查询状态:res.state

来查询任务的状态

Django使用Celery异步任务队列的使用

4与Django集成

上面简单介绍了celery异步任务的基本方法,结合我们实际的应用,我们需要与Django一起使用,下面介绍如何与Django结合。

4.1与Django集成方法

与Django集成有两种方法:

  1. Django 1.8 以上版本:与Celery 4.0版本集成
  2. Django 1.8 以下版本:与Celery3.1版本集成,使用django-celery库

今天我们介绍celery4.0 和django 1.8以上版本集成方法。

4.2 创建项目文件

创建一个项目:名字叫做proj

- proj/
 - proj/__init__.py
 - proj/settings.py
 - proj/urls.py
 - proj/wsgi.py
- manage.py

创建一个新的文件: proj/proj/mycelery.py

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
 
# 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 don't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')
 
# Load task modules from all registered Django app configs.
app.autodiscover_tasks()

在proj/proj/__init__.py:添加

from __future__ import absolute_import, unicode_literals
 
# This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .mycelery import app as celery_app
 
__all__ = ['celery_app']

4.3 配置Celery

我们在mycelery.py文件中说明celery的配置文件在settings.py中,并且是以CELERY开头。

app.config_from_object('django.conf:settings', namespace='CELERY')

在settings.py文件中添加celery配置:

Django使用Celery异步任务队列的使用

我们的配置是使用redis作为消息队列,消息的代理和结果都是用redis,任务的序列化使用json格式。

重要:redis://127.0.0.1:6379/0这个说明使用的redis的0号队列,如果有多个celery任务都使用同一个队列,则会造成任务混乱。最好是celery实例单独使用一个队列。

4.4创建APP

创建Django的App,名称为celery_task,在app目录下创建tasks.py文件。

完成后目录结构为:

├── celery_task
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tasks.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── proj
│ ├── celery.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── templates

4.5编写task任务

编辑任务文件

tasks.py

在tasks.py文件中添加下面代码

# Create your tasks here
from __future__ import absolute_import, unicode_literals
from celery import shared_task

@shared_task
def add(x, y):
 return x + y
 
@shared_task
def mul(x, y):
 return x * y
 
@shared_task
def xsum(numbers):
 return sum(numbers)

启动celery:celery -A proj.mycelery worker -l info

说明:proj 为模块名称,mycelery 为celery 的实例所在的文件。

启动成功打印:

Django使用Celery异步任务队列的使用

4.6在views中调用任务

在views中编写接口,实现两个功能:

  1. 触发任务,然后返回任务的结果和任务ID
  2. 根据任务ID查询任务状态

代码如下:

Django使用Celery异步任务队列的使用

启动django。

新开一个会话启动celery;启动命令为:celery ?A proj.mycelery worker ?l info

访问 http://127.0.0.1:8000/add ,可以看到返回的结果。

Django使用Celery异步任务队列的使用

在celery运行的页面,可以看到下面输出:

Django使用Celery异步任务队列的使用

4.7在views中查询任务状态

有的时候任务执行时间较长,需要查询任务是否执行完成,可以根据任务的id来查询任务状态,根据状态进行下一步操作。

可以看到任务的状态为:SUCCESS

Django使用Celery异步任务队列的使用

5Celery定时任务

Celery作为异步任务队列,我们可以按照我们设置的时间,定时的执行一些任务,例如每日数据库备份,日志转存等。

Celery的定时任务配置非常简单:

定时任务的配置依然在setting.py文件中。

说明:如果觉得celery 的数据配置文件和Django 的都在setting.py 一个文件中不方便,可以分拆出来,只需要在mycelery.py 的文件中指明即可。

app.config_from_object('django.conf:yoursettingsfile', namespace='CELERY')

5.1任务间隔运行

#每30秒调用task.add
from datetime import timedelta

CELERY_BEAT_SCHEDULE = {
 'add-every-30-seconds': {
  'task': 'tasks.add',
  'schedule': timedelta(seconds=30),
  'args': (16, 16)
 },
}

5.2定时执行

定时每天早上7:30分运行。

注意:设置任务时间时注意时间格式,UTC时间或者本地时间。

#crontab任务
#每天7:30调用task.add
from celery.schedules import crontab

CELERY_BEAT_SCHEDULE = {
 # Executes every Monday morning at 7:30 A.M
 'add-every-monday-morning': {
  'task': 'tasks.add',
  'schedule': crontab(hour=7, minute=30),
  'args': (16, 16),
 },
}

5.3定时任务启动

配置了定时任务,除了worker进程外,还需要启动一个beat进程。

Beat进程的作用就相当于一个定时任务,根据配置来执行对应的任务。

5.3.1  启动beat进程

命令如下:celery -A proj.mycelery beat -l info

Django使用Celery异步任务队列的使用

5.3.2  启动worker进程

Worker进程启动和前面启动命令一样。celery ?A proj.mycelery worker ?l info

Django使用Celery异步任务队列的使用

6 Celery深入

Celery任务支持多样的运行模式:

  1. 支持动态指定并发数 --autoscale=10,3 (always keep 3 processes, but grow to 10 if necessary).
  2. 支持链式任务
  3. 支持Group任务
  4. 支持任务不同优先级
  5. 支持指定任务队列
  6. 支持使用eventlet模式运行worker

例如:指定并发数为1000

celery -A proj.mycelery worker -c 1000

这些可以根据使用的深入自行了解和学习。

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

Python 相关文章推荐
Python对字符串实现去重操作的方法示例
Aug 11 Python
python中abs&map&reduce简介
Feb 20 Python
python模仿网页版微信发送消息功能
Feb 24 Python
python 数字类型和字符串类型的相互转换实例
Jul 17 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
Dec 05 Python
python turtle库画一个方格和圆实例
Jun 27 Python
python对数组进行排序,并输出排序后对应的索引值方式
Feb 28 Python
新建文件时Pycharm中自动设置头部模板信息的方法
Apr 17 Python
如何解决pycharm调试报错的问题
Aug 06 Python
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
Oct 21 Python
PyQt5中QSpinBox计数器的实现
Jan 18 Python
python Protobuf定义消息类型知识点讲解
Mar 02 Python
特征脸(Eigenface)理论基础之PCA主成分分析法
Mar 13 #Python
python Celery定时任务的示例
Mar 13 #Python
人脸识别经典算法一 特征脸方法(Eigenface)
Mar 13 #Python
Python cookbook(数据结构与算法)从序列中移除重复项且保持元素间顺序不变的方法
Mar 13 #Python
Python+Django搭建自己的blog网站
Mar 13 #Python
python实现人脸识别经典算法(一) 特征脸法
Mar 13 #Python
tensorflow实现softma识别MNIST
Mar 12 #Python
You might like
PHP实现将标点符号正则替换为空格的方法
2017/08/09 PHP
PHP基于MySQLI函数封装的数据库连接工具类【定义与用法】
2017/08/11 PHP
PHP中localeconv()函数的用法
2019/03/26 PHP
php模式设计之观察者模式应用实例分析
2019/09/25 PHP
关于Laravel-admin的基础用法总结和自定义model详解
2019/10/08 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
cnblogs 代码高亮显示后的代码复制问题解决实现代码
2011/12/14 Javascript
javascript实现信息的显示和隐藏如注册页面
2013/12/03 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
Jquery实现纵向横向菜单
2016/01/24 Javascript
node.js从数据库获取数据
2016/05/08 Javascript
js获取鼠标点击的对象,点击另一个按钮删除该对象的实现代码
2016/05/13 Javascript
详解js运算符单竖杠“|”与“||”的用法和作用介绍
2016/11/04 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
2018/04/26 jQuery
解决layer.prompt无效的问题
2019/09/24 Javascript
ZK中使用JS读取客户端txt文件内容问题
2019/11/07 Javascript
js实现飞机大战游戏
2020/08/26 Javascript
python实现DNS正向查询、反向查询的例子
2014/04/25 Python
Python itertools模块详解
2015/05/09 Python
Python中XlsxWriter模块简介与用法分析
2018/04/24 Python
解决PyCharm同目录下导入模块会报错的问题
2018/10/13 Python
python 函数中的内置函数及用法详解
2019/07/02 Python
Python正则表达式匹配日期与时间的方法
2019/07/07 Python
python3中eval函数用法使用简介
2019/08/02 Python
Python爬虫爬取煎蛋网图片代码实例
2019/12/16 Python
使用 Python 读取电子表格中的数据实例详解
2020/04/17 Python
使用before和:after伪类制作css3圆形按钮
2014/04/08 HTML / CSS
高中同学聚会邀请函
2014/01/11 职场文书
《赵州桥》教学反思
2014/02/17 职场文书
初中三好学生自我鉴定
2014/04/07 职场文书
老师对学生的寄语
2014/04/09 职场文书
快餐公司创业计划书
2014/04/29 职场文书
职务说明书范文
2014/05/07 职场文书
2015民办小学年度工作总结
2015/05/26 职场文书
幼儿园教师教学反思
2016/03/02 职场文书
python如何正确使用yield
2021/05/21 Python