Celery 的學習筆記--tornado異步開發的好朋友

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章