天天看點

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見下圖
           
Celery 的學習筆記--tornado異步開發的好朋友<一>

RabbitMQ 是AMPQ進階消息隊列協定的實作,也是celer預設的Broker,是以我們再這裡就用它了

RabbitMQ安裝:

yum install rabbitmq
or
apt-get install rabbitmq
           

安裝後要啟動它再能有效果,不然你寫的程式是連接配接不到Broker的

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://[email protected]//')

@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

2.4調用task

打開python輸入

from tasks import add

add.delay(4, 4)

這裡你肯定有疑問了——為什麼調用不直接調用add(),反而要調用add.delay().除了delay 還有其他的調用方式麽?

2.5 解開疑問

我們在官方文檔中找到了這個:

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

有三種調用方式。

第一種 例如

add.apply_async(args=[,])
           

第二種

add.delay(,)
           

其實第一種跟第二種是差不多的。不過唯一的差別在于第二種調用起來更加自由一些。官網說第二種是第一種的捷徑,隻不過不支援執行選項。

舉個例子就可以清楚的對比他們了:

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

           

第三種

直接調用,這樣直接調用中間人是不會發送它的,我們打開worker seviec 是不會看見它出現的痕迹的。

PS:一般情況下建議使用apply_async