RabbitMq +Celery(三)

一、Celery簡介

Celery 本身不是任務隊列, 是管理分佈式任務隊列的工具. 它封裝了操作常見任務隊列的各種操作, 我們使用它可以快速進行任務隊列的使用與管理.Celery是一個專注於實時處理和任務調度的分佈式任務隊列。同時提供操作和維護分佈式系統所需的工具,它的基本工作就是管理分配任務到不同的服務器,並且取得結果。至於說服務器之間是如何進行通信的?這個Celery本身不能解決。

Celery在執行任務時需要一個消息中間件來接收和發送任務消息,以及存儲任務結果,一般使用RabbitMQ 或 Redis,我們這裏只討論Celery+RabbitMQ,其他的組合方式讀者可以查閱更多資料。

所謂任務就是消息, 消息包含有效載荷(payload)和標籤(label),有效載荷中包含要執行任務傳輸需要的全部數據,可以輕鬆實現任務的異步處理;標籤描述了有效載荷,並決定誰獲得消息。舉個栗子:AMQP只會用標籤表述一條消息(一個交換器的名稱和可選的主題標記),然後把消息交由rabbit,rabbit會根標籤把消息發送給感興趣的接收方,但是接收方只根據規則接收消息(有效載荷),並不會接收標籤,也就是接收方不會知道是誰發送了消息。

優點:

簡單:一旦熟悉了Celery的工作流程後,配置和使用是比較簡單的。

高可用:當任務執行失敗或執行過程中發生連接中斷,Celery 會自動嘗試重新執行任務。

快速:一個單進程的Celery每分鐘可處理上百萬個任務。

靈活: Celery的大部分組件都可以被擴展及自定製。

 

二. celery 組件

1. Celery 扮演生產者和消費者的角色,

Celery Beat : 任務調度器. Beat 進程會讀取配置文件的內容, 週期性的將配置中到期需要執行的任務發送給任務隊列.

Celery Worker : 執行任務的消費者, 通常會在多臺服務器運行多個消費者, 提高運行效率.

Broker : 消息代理, 隊列本身. 也稱爲消息中間件. 接受任務生產者發送過來的任務消息, 存進隊列再按序分發給任務消費方(通常是消息隊列或者數據庫).

Celery默認的Broker是RabbitMQ

Producer : 任務生產者. 調用 Celery API , 函數或者裝飾器, 而產生任務並交給任務隊列處理的都是任務生產者.

Result Backend : 任務處理完成之後保存狀態信息和結果, 以供查詢.

Celery架構圖

2. 產生任務的方式 :

   1.發佈者發佈任務(WEB 應用)

   2.任務調度按期發佈任務(定時任務)

3.依賴庫

    kombu : Celery 自帶的用來收發消息的庫, 提供了符合 Python 語言習慣的, 使用 AMQP 協議的高級接口.

4.序列化

    在客戶端和消費者之間傳輸數據需要 序列化和反序列化. Celery 支出的序列化方案如下所示:

三、Celery+RabbitMQ是如何工作的?

關於Celery和RabbitMQ的協作方式,可以通過工作上的一些案例來說明:

假設A公司最近在開下年度工作會議,會議上要確定下一年的工作內容和計劃,參會人員有老闆(下發任務者)、部門主管(Celery分配任務者)、部門員工(工作者)、老闆祕書(溝通協調者RabbitMQ)。

那麼這場會議首先需要確定的是下一年的具體工作內容,這裏就稱之爲“任務內容”。比如老闆說我們下一年要開發出一款社交類APP產品,部門主管表示贊同,於是便愉快地定下了具體的工作任務(task),當然開發一款社交類APP產品是這個項目的總任務,其中可以細分成很多小的任務,比如業務流程是怎麼樣的?界面怎麼設計等。 

在確定了具體工作任務後,老闆便把這個項目交給了部門主管(Celery),部門主管確定部門員工中誰去完成這項任務,於是指定某個人(Worker),也可以多個人。 

發佈工作任務的人是老闆(下發任務者),他指定了部門主管(Celery)什麼時候去完成哪些任務,並要求獲取反饋信息。但有一點需要注意,老闆只管佈置任務,不參與具體的任務分配,這個任務分配的工作是交給部門主管(Celery)去執行。 

項目之初,老闆(下發任務者)通過公司會議將任務傳遞給部門主管(Celery),部門主管通過部門會議將任務分配給員工(Worker),過段時間再將任務結果反饋給老闆。然而隨着任務越來越多,部門主管發現任務太多,每個任務都要反饋結果,記不住,也容易弄亂,導致效率下降。 

在召開會議商量了一番後,老闆祕書(溝通協調者RabbitMQ)站起來說:“我有個提議,老闆每天將佈置的任務寫成一張紙條放到我這,然後部門主管每天早上來取並交給員工,至於紙條上的任務如何分配,部門主管決定就行,但是要將結果同樣寫一張紙條反饋給我,我再交給老闆。這樣老闆只負責下發任務,我只負責保管任務紙條,部門主管只負責分配任務並獲取反饋,員工只負責按任務工作。大家職責都很明確,效率肯定會更高。”至此,老闆與員工的溝通問題也解決了。

四、使用Celery+RabbitMq

1.Celery安裝使用

Celery是一個Python的應用,而且已經上傳到了PyPi,所以可以使用pip或easy_install安裝:

pip install celery

pip instal kombu

 

2.創建Application和Task

Celery的默認broker是RabbitMQ,僅需配置一行就可以:

broker_url = 'amqp://guest:guest@localhost:5672//'

 

創建一個Celery Application用來定義任務列表。

實例化一個Celery對象app,然後通過@app.task 裝飾器註冊一個 task。任務文件就叫tasks.py:

from celery import Celery

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

@app.task

def add(x, y):   

        return x + y
 

 

3.運行 worker,啓動Celery Worker來開始監聽並執行任務

在 tasks.py 文件所在目錄運行

$ celery worker -A tasks.app -l INFO

這個命令會開啓一個在前臺運行的 worker,解釋這個命令的意義:

worker: 運行 worker 模塊。

-A: –app=APP, 指定使用的 Celery 實例。

-l: –loglevel=INFO, 指定日誌級別,可選:DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL

其它常用的選項:

-P: –pool=prefork, 併發模型,可選:prefork (默認,multiprocessing), eventlet, gevent, threads.

-c: –concurrency=10, 併發級別,prefork 模型下就是子進程數量,默認等於 CPU 核心數

完整的命令行選項可以這樣查看:

$ celery worker --help

 

4.調用Task

再打開一個終端, 進行命令行模式,調用任務。

from tasks import add

add.delay(1,2)

add.apply_async(args=(1,2))

上面兩種調用方式等價,delay() 方法是 apply_async() 方法的簡寫。這個調用會把 add 操作放入到隊列裏,然後立即返回一個 AsyncResult 對象。如果關心處理結果,需要給 app 配置 CELERY_RESULT_BACKEND,指定一個存儲後端保存任務的返回值。

七、在項目中的簡單使用流程

1)RabbitMQ所在服務器,啓動crontab設置  crontable -user user -e設置定時執行celery application應用。

python tasks.py day 

2)在task.py文件裏面啓動一個叫做app的Celery Application,編寫一個app.task函數來produce 任務到rabbitmq。

app = Celery()

app.config_from_object(celeryconfig)

 

3)在每個worker裏面通過命令啓動worker消費任務

$ celery worker -A tasks.app -l INFO

 

 

 

 

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