您的位置:首页 > 其它

Celery 的学习笔记--tornado异步开发的好朋友<一>

2015-05-30 16:08 525 查看

1.前言

这段日子在用tornado 在sae 上搭建一些东西。tornado这个框架是个很不错的东西,在网上看了很多人的测试报告,在python中的几个框架里,tornado处理相同量的速度是最快的。这就归功于tornado的异步机制了。

 不过tornado的异步实现起来并不是那么简单,即使你加@tornado.web.asynchronous 装饰器,然后 yield  tornado.gen.Task(xxxxx,x,x),如果你编写的客户端不是异步的,再怎样负荷规范的写代码也不能异步的调用啊。这样假设一个请求有10秒,那你的线程就要阻塞10妙。这种情况相当的严重啊。

  根据网上的搜索,终于找到了 celery 这个东西。不过网上对这个东西的教程真是少的可怜,没办法只能通过阅读celery的官方文档自己学习。



2.认识CELERY

2.1 环境搭建

由于我是在tornado中搭建的所以必须要安装两样东西 celery和tornado-celery 。


2.1.1 celery 安装

python easy_install celery

或者 
pip install celery



2.12 tornado-celery 安装

tornado-celery 是基于celery的tornado客户端,通过tornado-celery可以将耗时任务加入到任务队列中处理,在celery中创建任务,tornado中就可以像调用AsyncHttpClient一样调用这些任务。

下载地址https://github.com/mher/tornado-celery

下载解压后

python  setup.py install

或者通过pip 和easy_install 的方法安装



2.13 broker(中间人)安装

至于这个中间人,至于安装了有什没用,怎么用?安装好了之后在下面的学习过程中我再详细告诉大家。
 不过大家可以先有个大概的了解--celery需要一个解决方案来发送和接收消息,而这个解决方案就是中间人了,既然是中间人那么就应独立分开于Server了。


celer 支持的Broker见下图




RabbitMQ 是AMPQ高级消息队列协议的实现,也是celer默认的Broker,所以我们再这里就用它了

RabbitMQ安装:

yum install rabbitmq
or
apt-get install rabbitmq


安装后要启动它再能有效果,不然你写的程序是连接不到Broker的

sudo rabbitmq-server -detached



2. 窥探 celery

2.1创建celery实例

这个最重要的一步也是第一步,通过这个celery实例我们可以做我们想做的一切。对于小项目我们用单一模块就够了,对于大项目我们要创建一个[专用模块](http://docs.celeryproject.org/en/master/getting-started/next-steps.html#project-layout%20%E4%B8%93%E7%94%A8%E6%A8%A1%E5%9D%97) (我们先看代码再分析)



2.2最简单的Celery代码

tasks.py

from celery import Celery

app = Celery('tasks', broker='amqp://guest@localhost//')

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


2.2.1 分析

调用Celery 创建Celery的实例。Celery中要有两个参数,

    第一个参数(The first argument to Celery is the name of the current module)是当前模块的名称,

    第二个参数是broker 关键字参数指定要使用的消息代理URL,这里是RabbitMQ,也是默认选项。


我们在add()函数前加了装饰器@app.task,表明我们定义了这个任务

2.3启动worker

celery -A tasks worker --loglevel=info



2.4调用task

打开python输入

from tasks import add

add.delay(4, 4)

这里你肯定有疑问了——为什么调用不直接调用add(),反而要调用add.delay().除了delay 还有其他的调用方式麽?


2.5 解开疑问

我们在官方文档中找到了这个:



有三种调用方式。

第一种 例如

add.apply_async(args=[2,2])


第二种

add.delay(2,2)


其实第一种跟第二种是差不多的。不过唯一的区别在于第二种调用起来更加自由一些。官网说第二种是第一种的捷径,只不过不支持执行选项。

举个例子就可以清楚的对比他们了:

task.delay(arg1, arg2, kwarg1='x', kwarg2='y')
#delay更像是常规的地调用
task.apply_async(args=[arg1, arg2], kwargs={'kwarg1': 'x', 'kwarg2': 'y'})


不过经过我的测试使用delay()响应速度更快。

#add.apply_async([4,4])

[2015-05-30 16:49:59,357: INFO/MainProcess] Received task: tasks1.add[8d378500-8b07-40de-b18f-20f003d67225]
[2015-05-30 16:49:59,359: INFO/MainProcess] Task tasks1.add[8d378500-8b07-40de-b18f-20f003d67225] succeeded in 0.000862701999722s: 8
----------------
#add.delay(4,4)

[2015-05-30 16:50:11,748: INFO/MainProcess] Received task: tasks1.add[dfd494c1-d57b-482c-94ab-3b56f05d6879]
[2015-05-30 16:50:11,750: INFO/MainProcess] Task tasks1.add[dfd494c1-d57b-482c-94ab-3b56f05d6879] succeeded in 0.000724498999261s: 8


第三种

add(4,4)


直接调用,这样直接调用中间人是不会发送它的,我们打开worker seviec 是不会看见它出现的痕迹的。

PS:一般情况下建议使用apply_async
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: