一、 基本介绍

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. 增加github访问速度

    转自:https://blog.csdn.net/qq_38977097/article/details/80770987 原因 为什么慢?github的CDN被某墙屏了. 解决方法 绕过dns解析, ...

  2. scikit-learn机器学习(四)使用决策树做分类,并画出决策树,随机森林对比

    数据来自 UCI 数据集 匹马印第安人糖尿病数据集 载入数据 # -*- coding: utf-8 -*- import pandas as pd import matplotlib matplot ...

  3. python之inspect模块

      inspect模块主要提供了四种用处: 1.对是否是模块.框架.函数进行类型检查 2.获取源码 3.获取类或者函数的参数信息 4.解析堆栈 回到顶部 一.type and members 1. i ...

  4. python多线程、线程锁

    1.python多线程 多线程可以把空闲时间利用起来 比如有两个进程函数 func1.func2,func1函数里使用sleep休眠一定时间,如果使用单线程调用这两个函数,那么会顺序执行这两个函数 也 ...

  5. springMVC配置文件学习

    spring配置文件分为dao层,web层,service层,三层配置 这三层配置中, dao层对应数据库的配置:进行数据库相关和model实体类的配置 web层对应controller包中配置:设置 ...

  6. CG标准函数

  7. 学习SpringBoot整合SSM三大框架源码之SpringBoot

    Spring Boot源码剖析 一.Spring Boot 项目的启动入口流程分析 Spring Boot项目的启动入口main线程上有一个@SpringBootApplication( @Confi ...

  8. from提交数据,高级选择器,伪类选择器,前端样式等

    1. form提交数据 get: 不安全的提交数据,高效 post: 安全的提交数据,低效 前台都可以给后台提交数据,后台一定会给前台一个反馈结果 2. 高级选择器 <!DOCTYPE html ...

  9. 《精通并发与Netty》学习笔记(13 - 解决TCP粘包拆包(一)概念及实例演示)

    一.粘包/拆包概念 TCP是一个“流”协议,所谓流,就是没有界限的一长串二进制数据.TCP作为传输层协议并不不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行数据包的划分,所以在业务上认 ...

  10. 首款物联网防火墙himqtt开源

    随着5G的推进和物联网的快速推进,MQTT已然是物联网(Internet of Things,IoT)不可或缺的标准协议,预计到2025年将有超过750亿台设备连接到互联网,但物联网方面的防火墙很少. ...