一、 基本介绍

Celery是一个专注于实时处理和任务调度的分布式任务队列。所谓任务就是消息,消息中的有效载荷中包含要执行任务需要的全部数据。

使用Celery常见场景:

  1. Web应用。当用户触发的一个操作需要较长时间才能执行完成时,可以把它作为任务交给Celery去异步执行,执行完再返回给用户。这段时间用户不需要等待,提高了网站的整体吞吐量和响应时间。
  2. 定时任务。生产环境经常会跑一些定时任务。假如有上千台的服务器、上千种任务,定时任务的管理会很困难,Celery可以帮助我们快速在不同的机器设定不同种任务。
  3. 其他可以异步执行的任务。为了充分提高网站性能,对于请求和响应之外的那些不要求必须同步完成的附加工作都可以异步完成。比如发送邮件/短信、推送消息、清理/设置缓存等。

Celery特性:

  • 方便地查看定时任务的执行情况,比如执行是否成功、当前状态、执行任务花费的时间等。
  • 可以使用功能齐备的管理后台或者命令行添加、更新、删除任务。
  • 方便把任务和配置管理相关联。
  • 可选多进程、Evenlent和Gevent三种模式并发执行。
  • 提供多种错误处理机制。
  • 提供多种任务原语,方便实现任务分组、拆分和调用链。
  • 支持多种消息代理和存储后端。

Celery架构图:

产生任务的方式有两种:

  1. 发布者发布任务(Web应用)
  2. 任务调度按期发布任务(定时任务)

Celery组件介绍:

  • Celery Beat: 任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列。
  • Celery Worker: 执行任务的消费者,通常会在多台服务器运行多个消费者来提高执行效率。
  • Broker: 消息代理,或者叫做消息中间件,接受任务生产者发送过来的任务消息,存进队列在按序分发给任务消费方。
  • Producer: 调用Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者。
  • Result Backend: 任务处理完后保存状态信息和结果,以供查询。Celery默认支持Redis、RabbitMQ、MongoDB、Django ORM SQLAlchemy等方式。

Celery目前支持RabbitMQ、Redis、MongoDB、Beanstalk、Zookeeper、SQLAlchemy等作为消息代理,但用于生产环境只有RabbitMQ和Redis,官方推荐RabbitMQ来作为Celery的消息代理。

在客户端和消费者之间传输数据需要序列化和反序列化,Celery支持的序列化方案有pickle,json,yaml,msgpack,一般使用json

二、安装配置Celery

为了提供更高的性能,采用如下方案:

  • 选择RabbitMQ作为消息代理。
  • RabbitMQ的Python客户端选择librabbitmq这个C库。
  • 选择Msgpack做序列化
  • 选择Redis做结果存储
sudo apt-get install rabbitmq-server
sudo apt-get install redis-server
sudo pip install "celery[librabbitmq,redis,msgpack]"

三、示例演示

项目目录结构

tree project
project
├── celeryconfig.py
├── celery.py
├── __init__.py
└── tasks.py

主程序celery.py:

#!/usr/bin/env python
# -*- coding:utf-8 -*- # 拒绝隐式引入,因为celery.py的名字和celery的包名冲突,需要使用这条语句让程序正确运行
from __future__ import absolute_import from celery import Celery # app是 Celery类的实例,创建的时候添加了project.tasks这个模块,也就是包含了project/tasks.py这个文件
app = Celery('project', include=['project.tasks']) # 把Celery配置存放进project/celeryconfig文件,使用app.config_from_object加载配置
app.config_from_object('project.celeryconfig') if __name__ == '__main__':
app.start()

任务函数文件tasks.py:

#!/usr/bin/env python
# -*- coding:utf-8 -*- from __future__ import absolute_import from project.celery import app # 让任务函数生效的方法是添加app.task装饰器
@app.task
def add(x, y):
return x + y

配置文件celeryconfig.py:

# -*- coding:utf-8 -*-
BROKER_URL = 'amqp://guest:guest@localhost:5672//' # 使用RabbitMQ作为消息代理
CELERY_TASK_PROTOCOL = 1 # 现在celery升级到了4.0,是老版本的librabbitmq与最新的celery4.0 Message Protocol协议不兼容,celery4.0默认使用Task messages Version 2 ,而librabbitmq使用Task messages Version 1
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' # 把结果存在Redis
CELERY_TASK_SERIALIZER = 'msgpack' # 任务序列化肯反序列化使用msgpack方案
CELERY_RESULT_SERIALIZER = 'json' # 读取任务结果一般性能要求不高,所以使用可读性更好的json
CELERY_TASK_RESULT_EXPIRES = 60 * 60 * 24 # 任务过期时间
CELERY_ACCEPT_CONTENT = ['json', 'msgpack'] # 指定接收的内容类型

启动消费者:

celery -A project.celery  worker -l info
终端界面提供了消息代理和存储结果的地址、并发数量、任务列表、交换类型等

开启另一个终端,用ipython调用add函数

In [1]: from project.tasks import add

In [2]: r = add.delay(1,3)

In [3]: r
Out[3]: <AsyncResult: a14d2045-ad40-4240-bbcf-1a8f07899485> In [4]: r.result
Out[4]: 4 In [5]: r.status
Out[5]: u'SUCCESS' In [6]: r.successful()
Out[6]: True In [7]: r.backend
Out[7]: <celery.backends.redis.RedisBackend at 0x7faae433a450> # 保存在redis中

任务的task_id根据上面提到的task_id获得,可以用下面方法获得结果

# 方法一:

In [9]: task_id = 'a14d2045-ad40-4240-bbcf-1a8f07899485'

In [10]: add.AsyncResult(task_id).get()
Out[10]: 4 # 方法二: In [12]: from celery.result import AsyncResult In [13]: AsyncResult(task_id).get()
Out[13]: 4 

四、Django中测试Celery异步邮件

下面在django中模拟一下如何用celery:

首先先看没有用celery的程序

这就造成不良好的用户体验了,那你先给用户返回程序执行成功,再在后台执行这5秒

下面就用selery

1.安装selery ,不写版本号默认最新,新版本只需要安装一个celery

pip install celery==3.1.25

pip install celery-with-redis==3.0

pip install django-celery==3.2.1

2.在应用目录下创建名为task.py的文件,该文件用于封装耗时任务的

3.配置setting.py

3.1注册进app

INSTALLED_APP=[

. . . .  +

‘djcelery’]

3.2 再加上,

import djcelery

djcelery.setup_loader()

BROKER_URL='redis://:密码@数据库ip地址:6379/0'      #格式不能错 ,注意分号

CELERY_IMPORTS=(‘myApp.task’)        #任务文件

4.迁移,生成celery需要的表

python manage.migrate

5.将名为celery.py的文件加入到同工程目录同名的目录下,这个文件是官网给我们写好的

from __future__ import absolute_import

import os
from celery import Celery
from django.conf import settings os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'whthas_home.settings') app = Celery('project') #这里改成自己工程名
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))

6.修改与工程目录同名目录下的__init__.py文件,上图红色箭头指处

from project.celery import app as celery_app

7.将耗时程序封装成任务,在task.py文件里

在view.py文件里

这时你去跑程序,会发现很快,但却没有打印开始与结束这两句,其实它没有执行到耗时程序,还缺最后一步

8.启动redis,确保服务器启动

9.启动worker,在黑窗口进入工程目录下,执行命令

python manage.py celery worker --loglevel=info

访问浏览器,就可以看到很快的返回程序执行成功,而耗时程序在黑窗口进行打印:开始程序执行,等待5秒,结束程序执行

相互不影响

浏览器返回

黑窗口打印

 

Celery 初步使用心得的更多相关文章

  1. 关于使用CELERY的一点心得

    使用也有大半年了.稳定性没话说啊. 但有一个坑,是我以前没注意的,记录下来. 就是本来一个任务是可以异步并行执行的..但如何需要CELERY的执行结果来作判断的话,就会变得异步串行的. 这要值得注意. ...

  2. Python之celery的简介与使用

    celery的简介   celery是一个基于分布式消息传输的异步任务队列,它专注于实时处理,同时也支持任务调度.它的执行单元为任务(task),利用多线程,如Eventlet,gevent等,它们能 ...

  3. celery+Rabbit MQ实战记录

    基于以前的一篇文章,celery+Rabbit MQ的安装和使用, 本文更加详细的介绍如何安装和使用celey, Rabbit MQ. 并记录在使用celery时遇到的一些问题. 1.安装 Rabbi ...

  4. celery 分布式异步任务框架(celery简单使用、celery多任务结构、celery定时任务、celery计划任务、celery在Django项目中使用Python脚本调用Django环境)

    一.celery简介: Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async tas ...

  5. Linux学习心得之 双显卡、中文输入法及svn初步使用

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Linux学习心得之 双显卡.中文输入法及svn初步使用 1.前言 2.Linux双显卡解决 ...

  6. Django搭配Celery进行异步/定时任务(一)初步搭建

    以下需求场景很常见: 1. 用户点击页面按钮,请求后台进行一系列耗时非常高的操作,页面没有响应/一直Loading,用户体验非常不好. 2. 某些数据需要预先处理,每天凌晨的时候进行运算,大约半小时到 ...

  7. bootstrap使用心得及css模块化的初步尝试

    第一次用bootstrap到实战项目,是一个企业门户站,可以说是强行拿bootstrap上来练手,感觉并不适合. 我是用的less编译bootstrap文件,直接改less变量.然后把不可重用的部分, ...

  8. 初步接触html心得

    接触HTML大概有七天,做一下小总结,过过记忆. html大致可分为三部分:Dtd头.Head.Body三大部分. Dtd头:是用于浏览器编辑的,也就是俗话说的给电脑看的的东西. Head:内细分下大 ...

  9. JAVA编程心得-多态设计初步

    面向对象的思想中,封装,继承,多态作为特性会在开发中广泛应用,一个健壮的系统除了功能强大以外,它的可扩展性应该也很强,多态恰好应用了这个思路. 下面我以杨小聪去某地的方式为例,我们知道首先杨小聪要去某 ...

随机推荐

  1. CentOS7 升级 python3 过程及注意

    • 从官网下载python3的压缩包,解压(以3.5.1版本为例)• 创建安装目录(自定义)sudo mkdir /usr/local/python3• cd 进入解压目录sudo ./configu ...

  2. php微信支付企业付款到零钱报错call faild, errorCode:58

    这个报错一般是自己证书目录不是绝对目录,正确的目录结构应该是网站根目录下的:“C:\PHPWAMP_IN1\wwwroot\XXXX\XXXX.pem”.          还要注意的是文件夹命名一定 ...

  3. 使用 bash 脚本把 GCE 的数据备份到 GCS

    目录 一.Google Cloud Storge 介绍 1.1.四种存储类别的比较 1.2.需求 1.3.给虚拟机添加授权认证 二.备份操作 2.1 创建存储分区 2.2 上传对象到存储分区 2.3 ...

  4. golang继承与接口

    继承 结构体 Go语言的结构体(struct)和其他语言的类(class)有同等的地位,但Go语言放弃了包括继 承在内的大量面向对象特性,只保留了组合(composition)这个最基础的特性. 组合 ...

  5. JS 正则表达式 控制文本框只能输入中文、英文、数字与指定特殊符号

    JS 正则表达式 控制文本框只能输入中文.英文.数字与指定特殊符号(屏蔽表情输入) onkeyup:释放键盘事件 onpaste:粘贴事件 oncontextmenu :鼠标右击事件 只能输入中文: ...

  6. AWK---linux系统三剑客(三)

    grep .sed.awk被称为linux中的"三剑客". grep 更适合单纯的查找或匹配文本 sed  更适合编辑匹配到的文本 awk  更适合格式化文本,对文本进行较复杂格式 ...

  7. 带你手写基于 Spring 的可插拔式 RPC 框架(四)代理类的注入与服务启动

    上一章节我们已经实现了从客户端往服务端发送数据并且通过反射方法调用服务端的实现类最后返回给客户端的底层协议. 这一章节我们来实现客户端代理类的注入. 承接上一章,我们实现了多个底层协议,procoto ...

  8. css常见双栏和三栏布局

    左侧固定右侧自适应 <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  9. SQLite进阶-17.视图

    目录 视图(View) 操作视图 更新视图 删除视图 查看所有的视图 视图(View) 视图是一个预定义的SQLite查询的形式存在的表的组合. 可以包含一个表的所有行或从一个或多个表选定行.可以从一 ...

  10. 2017"百度之星"程序设计大赛 - 资格赛 1002 度度熊的王国战略

    全局最小割 Stoer-Wagner (SW算法)优化 优化吃藕了,感谢放宽时限,感谢平板电视 (pb_ds) #include <iostream> #include <cstdi ...