Celery是一个“自带电池”的任务队列。易于使用,可以轻易入门,它遵照最佳实践设计,使产品可以扩展,或与其他语言集成,并且它自带了在生产环境中运行这样一个系统所需的工具和支持。本文介绍基础部分:

  • 选择和安装消息传输方式(中间人)。
  • 安装Celery并创建一个任务
  • 运行职程并调用任务
  • 追踪任务在不同状态间的迁移,并检视返回值

一、选择中间人

Celery需要一个发送和接收消息的解决方案,其通常以独立服务形式出现,称为消息中间人。

可行的选择包括:

RabbitMQ

RabbitMQ功能完备、稳定、耐用,并且安装简便,是生产环境的绝佳选择。

Redis

Redis也是功能完备的,但更容易受濡染终端或断电地阿莱数据丢失的影响。

使用数据库

不推荐把数据库用于消息队列,但对于很小的项目可能是合适的。

其他中间人

还有其他实验性传输实现:AmazonSQS、MongoDB和IronMQ。

二、安装Celery

Celery提交到Python Package Index上,可以使用Python标准工具pip进行安装:

$ pip install celery

三、应用

首先需要一个Celery实例:这个实例用于你想在celery中做一切事,它必须可以被其他模块导入。

我们简单的放在一个模块中,对于比较大的项目,可以创建一个独立模块。

创建tasks.py:

from celery import Celery

app = Celery('tasks', broker='redis://127.0.0.1:6379/3')

@app.task
def add(x, y):
return x + y

创建APP的时候,Celery方法的第一个参数是我们当前py文件的名字。broker是我们选择的中间人。上面的代码使用的是redis。

接下来我们可以先运行我们的工作任务。

$ celery -A tasks worker --loglevel=info

使用celery命令,第二个参数'tasks'还是我们的py文件名字,后面是指定日志级别。这条命令必须能找到我们的tasks文件才能运行起来。

接下来调用我们的任务:

>>> from tasks import add
>>> add.delay(1, 3)
<AsyncResult: 7217dee2-3869-4f5e-8ccc-3a3b3dd6a9d7> # 这里返回的是任务ID,而不是结果。

这样我们就实现了一个最简单的celery应用。

其他更多的参数命令,你可以通过下面的方式了解:

$ celery worker --help

$ celery help

关于调用我们的任务方式:

  • delay()
  • apply_async()
# delay()这个方法使用起来更方便一些,它能像调用普通函数一样调用我们的任务
task.delay(arg1, arg2, kwarg1='x', kwarg2='y') # 使用apply_async你还需要将参数进行整合
task.apply_async(args=[arg1, arg2], kwargs={'kwarg1': 'x', 'kwarg2': 'y'})

  

接下来说一下,在我们的应用中如何使用celery

项目布局:

proj/__init__.py
/celery.py
/tasks.py

项目中的celery.py

celery.py

from __future__ import absolute_import
from celery import Celery app = Celery('mysite', # 项目名称
broker='redis://127.0.0.1:6379/3', # 制定我们用的中间人
backend='redis://127.0.0.1:6379/5', # 定义回调中间人
include=['proj.tasks'],) app.conf.update(
result_expires=3600 # 设置过期时间
) if __name__ == '__main__':
app.start()

  

task.py

from __future__ import absolute_import
from .celery import app
import time @app.task(bind=True) # 指定bind=True,当前task函数第一个参数为task本身。
def add(self, x, y):
time.sleep(1)
self.update_state(state="PROGRESS", meta={'progress': 50})
# task使用update_state修改当前状态可以触发on_message回调函数
time.sleep(3)
self.update_state(state="PROGRESS", meta={'progress': 90})
time.sleep(1)
print(self.request.chain)
print(123456)
self.request.chain = None # 当使用chain同时调用多个task函数的时候,如果中间需要停止,可以使用self.request.chain = None
self.update_state(state="PROGRESS", meta={'result': x + y})
return x + y @app.task(bind=True)
def mul(self, x, y):
return x * y @app.task
def div(x, y):
return x / y

  

mysite/views.py

from celery import chain

from django.shortcuts import render, HttpResponse

from celery_work.tasks import add
from celery_work.tasks import mul
from celery_work.tasks import div
from celery_work.tasks import error_handler
# from celery_work.tasks import error_handler def test(request):
def on_raw_message(body):
print(body)
res = add.apply_async((1, 2)) print(res.get(on_message=on_raw_message, propagate=False))
# 注意这里使用了res.get(),所以并不是异步返回的,而是等拿到结果之后返回的
return HttpResponse('ok') # 异步方式处理函数,在add这个task函数中是有睡眠时间的,但是我们在发布任务之后就立即将任务ID返回给客户端了
def test0(request):
res = add.apply_async((1, 2))
return HttpResponse('async: %s' % res) # 没有中断的chain任务
def test1(request):
res = (mul.s(1, 2) | mul.s(3) | mul.s(3))()
# 另一种写法 chain(mul.s(1, 2), mul.s(3), mul.s(3))()
return HttpResponse(res.get()) # 有中断的chain任务,这里需要注意一下,我们在add这个函数中将chain终止了,res永远无法get到返回值
# 因为res是要取chain任务最后一个task函数的返回值,这样就要使用parent从最后一个task函数往前找,
# 直到找到终止chain任务的那个task函数,进行get
def test2(request):
res = (add.s(1, 2) | mul.s(3) | mul.s(3))()
print(res.parent.parent.get())
print(res.parent.parent.successful())
return HttpResponse('mul')

  

  

Celery初识及简单实例的更多相关文章

  1. Celery -- 分布式任务队列 及实例

    Celery 使用场景及实例 Celery介绍和基本使用 在项目中如何使用celery 启用多个workers Celery 定时任务 与django结合 通过django配置celery perio ...

  2. Hibernate(二)__简单实例入门

    首先我们进一步理解什么是对象关系映射模型? 它将对数据库中数据的处理转化为对对象的处理.如下图所示: 入门简单实例: hiberante 可以用在 j2se 项目,也可以用在 j2ee (web项目中 ...

  3. 最新 Eclipse IDE下的Spring框架配置及简单实例

    前段时间开始着手学习Spring框架,又是买书又是看视频找教程的,可是鲜有介绍如何配置Spring+Eclipse的方法,现在将我的成功经验分享给大家. 本文的一些源代码来源于码农教程:http:// ...

  4. 修改js confirm alert 提示框文字的简单实例

    修改js confirm alert 提示框文字的简单实例: <!DOCTYPE html> <html> <head lang="en"> & ...

  5. 利用navicat创建存储过程、触发器和使用游标的简单实例

    利用navicat创建存储过程.触发器和使用游标的简单实例 标签: navicat存储过程触发器mysql游标 2013-08-03 21:34 15516人阅读 评论(1) 收藏 举报  分类: 数 ...

  6. 【转】Android Https服务器端和客户端简单实例

    转载地址:http://blog.csdn.net/gf771115/article/details/7827233 AndroidHttps服务器端和客户端简单实例 工具介绍 Eclipse3.7 ...

  7. Centos7的安装、Docker1.12.3的安装,以及Docker Swarm集群的简单实例

    目录 [TOC] 1.环境准备 ​ 本文中的案例会有四台机器,他们的Host和IP地址如下 c1 -> 10.0.0.31 c2 -> 10.0.0.32 c3 -> 10.0.0. ...

  8. vue路由的简单实例

    vue2.0 和 vue1.0 路由的语法还是有点稍微的差别,下面介绍一下vue-router 2的简单实例: <!DOCTYPE html> <html lang="en ...

  9. Flume概述和简单实例

    Flume概述 Flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方( ...

随机推荐

  1. [AH2017/HNOI2017]大佬

    题目描述 人们总是难免会碰到大佬.他们趾高气昂地谈论凡人不能理解的算法和数据结构,走到任何一个地方,大佬的气场就能让周围的人吓得瑟瑟发抖,不敢言语. 你作为一个 OIER,面对这样的事情非常不开心,于 ...

  2. 戏说java与web

    slmgr.vbs /ipk NPPR9-FWDCX-D2C8J-H872K-2YT43教育版换回企业版 搜百度网盘  http://www.pansoso.com/ https://m.zhangl ...

  3. (转)ReentrantLock实现原理及源码分析

    背景:ReetrantLock底层是基于AQS实现的(CAS+CHL),有公平和非公平两种区别. 这种底层机制,很有必要通过跟踪源码来进行分析. 参考 ReentrantLock实现原理及源码分析 源 ...

  4. echarts Map(地图) 不同颜色区块显示

    以河南地图为例: 代码如下: <h3>天翼日必达完成率</h3> <div id="map" style="height:340px; te ...

  5. mysql常用的用户授权语句

    一:授权主要的 SQL //某个数据库所有的权限 ALL 后面+ PRIVILEGES GRANT ALL PRIVILEGES ON 库名.* TO '用户'@'%' IDENTIFIED BY ' ...

  6. Linux系统下DHCP服务安装部署和使用详解

    一.概述 DHCP :动态主机设置协议(英语:Dynamic Host Configuration Protocol,DHCP)是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:用于内部网或 ...

  7. Java基础--面向对象编程2(封装)

    1.封装的定义: 封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.  为什么需要封装?封装的作用和含义? 首先思考一个问题:当我们要 ...

  8. I/O模型系列之三:IO通信模型BIO NIO AIO

    一.传统的BIO 网络编程的基本模型是Client/Server模型,也就是两个进程之间进行相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的地址发起连接请 ...

  9. 【Unity游戏开发】你真的了解UGUI中的IPointerClickHandler吗?

    一.引子 马三在最近的开发工作中遇到了一个比较有意思的bug:“TableViewCell上面的某些自定义UI组件不能响应点击事件,并且它的父容器TableView也不能响应点击事件,但是TableV ...

  10. 使用容器编排工具docker swarm安装clickhouse多机集群

    1.首先需要安装docker最新版,docker 目前自带swarm容器编排工具 2.选中一台机器作为master,执行命令sudo docker  swarm init [options] 3,再需 ...