前言
Celery是一個異步任務隊列。它可以用於需要異步運行的任何內容。RabbitMQ是Celery廣泛使用的消息代理。在本這篇文章中,我將使用RabbitMQ來介紹Celery的基本概念,然後爲一個小型演示項目設置Celery 。最後,設置一個Celery Web控制檯來監視我的任務
基本概念
來!看圖說話:
-
Broker
Broker(RabbitMQ)負責創建任務隊列,根據一些路由規則將任務分派到任務隊列,然後將任務從任務隊列交付給worker -
Consumer (Celery Workers)
Consumer是執行任務的一個或多個Celery workers。可以根據用例啓動許多workers -
Result Backend
後端用於存儲任務的結果。但是,它不是必需的元素,如果不在設置中包含它,就無法訪問任務的結果
安裝Celery
首先,需要安裝好Celery,可以使用PyPI:
pip install celery
選擇一個Broker:RabbitMQ
爲什麼我們需要broker呢?這是因爲Celery本身並不構造消息隊列,所以它需要一個額外的消息傳輸來完成這項工作。這裏可以將Celery看作消息代理的包裝器
實際上,也可以從幾個不同的代理中進行選擇,比如RabbitMQ、Redis或數據庫(例如Django數據庫)
在這裏使用RabbitMQ作爲代理,因爲它功能完整、穩定,Celery推薦使用它。由於演示我的環境是在Mac OS中,安裝RabbitMQ使用Homebrew即可:
brew install rabbitmq
#如果是Ubuntu的話使用apt-get安裝
啓動RabbitMQ
程序將在/usr/local/sbin中安裝RabbitMQ,雖然有些系統可能會有所不同。可以將此路徑添加到環境變量路徑,以便以後方便地使用。例如,打開shell啓動文件~/.bash_profile添加:
PATH=$PATH:/usr/local/sbin
現在,可以使用rabbitmq-server命令啓動我們的RabbitMQ服務器。檢查RabbitMQ服務器成功啓動,將看到類似的輸出:
爲Celery配置RabbitMQ
RabbitMQ使用Celery之前,需要對RabbitMQ進行一些配置。簡單地說,我們需要創建一個虛擬主機和用戶,然後設置用戶權限,以便它可以訪問虛擬主機
# 添加用戶跟密碼
$ rabbitmqctl add_user test test123
# 添加虛擬主機
$ rabbitmqctl add_vhost test_vhost
# 爲用戶添加標籤
$ rabbitmqctl set_user_tags test test_tag
# 設置用戶權限
$ rabbitmqctl set_permissions -p test_vhost test ".*" ".*" ".*"
敲黑板!RabbitMQ中有三種操作:配置、寫入和讀取
上面命令末尾的字符串表示用戶test將擁有所有配置、寫入和讀取權限
演示項目
現在讓我們創建一個簡單的項目來演示Celery的使用
在celery.py中添加以下代碼:
from __future__ import absolute_import
from celery import Celery
app = Celery('test_celery',
broker='amqp://test:test123@localhost/test_vhost',
backend='rpc://',
include=['test_celery.tasks'])
在這裏,初始化了一個名爲app的Celery實例,將用於創建一個任務。Celery的第一個參數只是項目包的名稱,即“test_celery”。
broker參數指定代理URL,對於RabbitMQ,傳輸是amqp。
後端參數指定後端URL。Celery中的後端用於存儲任務結果。因此,如果需要在任務完成時訪問任務的結果,應該爲Celery設置一個後端。
rpc意味着將結果作爲AMQP消息發送回去,這對本次演示來說是一種可接受的格式
include參數指定了在Celery工作程序啓動時要導入的模塊列表。我們在這裏添加了tasks模塊,以便找到我們的任務。
在tasks.py這個文件中,定義了我們的任務add_longtime:
from __future__ import absolute_import
from test_celery.celery import app
import time
@app.task
def add_longtime(a, b):
print 'long time task begins'
# sleep 5 seconds
time.sleep(5)
print 'long time task finished'
return a + b
可以看到,導入了在前面的Celery模塊中定義的應用程序,並將其用作任務方法的裝飾器。另外注意!app.task只是一個裝飾器。此外,我們在add_longtime任務中休眠5秒,以模擬一個耗時較長的Task
在設置好Celery之後,我們需要開始運行任務,它包含在runs_tasks.py:
from .tasks import add_longtime
import time
if __name__ == '__main__':
result = add_longtime.delay(1,2)
#此時,任務還未完成,它將返回False
print 'Task finished? ', result.ready()
print 'Task result: ', result.result
# 延長到10秒以確保任務已經完成
time.sleep(10)
# 現在任務完成,ready方法將返回True
print 'Task finished? ', result.ready()
print 'Task result: ', result.result
這裏,我們使用delay方法調用任務add_longtime,如果我們想異步處理任務,就需要使用delay方法。此外,保存任務的結果並打印一些信息。如果任務已經完成,ready方法將返回True,否則返回False。result屬性是任務的結果,如果任務尚未完成,則返回None。
啓動Celery
現在,可以使用下面的命令啓動Celery(注:在項目文件夾中運行):
celery -A test_celery worker --loglevel=info
Celery成功連接到RabbitMQ,你會看到這樣的東西:
運行任務
再項目文件中輸入以下命令運行它:
python -m test_celery.run_tasks
查看Celery控制檯,看到運行任務:
[2020-05-15 17:15:21,508: INFO/MainProcess]
Received task: test_celery.tasks.add_longtime[25ba9c87-69a7-4383-b983-1cefdb32f8b3]
[2020-05-15 17:15:21,508: WARNING/Worker-3] long time task begins
[2020-05-15 17:15:31,510: WARNING/Worker-3] long time task finished
[2020-05-15 17:15:31,512: INFO/MainProcess]
Task test_celery.tasks.add_longtime[25ba9c87-69a7-4383-b983-1cefdb32f8b3] succeeded in 15.003732774s: 3
當Celery收到一個任務,它打印出任務名稱與任務id(在括號中):
Received task: test_celery.tasks.add_longtime[7d942984-8ea6-4e4d-8097-225616f797d5]
在這一行下面是我們的任務add_longtime打印的兩行,時間延遲爲5秒:
long time task begins
long time task finished
最後一行顯示我們的任務在5秒內完成,任務結果爲3:
Task test_celery.tasks.add_longtime[7d942984-8ea6-4e4d-8097-225616f797d5] succeeded in 5.025242167s: 3
在當前控制檯中,您將看到以下輸出:
實時監控Celery
Flower是一款基於網絡的Celery實時監控軟件。使用Flower,可以輕鬆地監視任務進度和歷史記錄
使用pip來安裝Flower:
pip install flower
要啓動Flower web控制檯,需要運行以下命令:
celery -A test_celery flower
Flower將運行具有默認端口5555的服務器,可以通過http://localhost:5555訪問web控制檯
好了,到這裏又到了跟大家說再見的時候了。我只是一個會寫爬蟲的段子手而已,一個希望有朝一日能夠實現財富自由,能夠早日榮歸故里的遊子罷了。希望我的文章能帶給您知識,帶給您幫助,帶給您歡笑!同時也謝謝您能抽出寶貴的時間閱讀,創作不易,如果您喜歡的話,點個贊再走吧。您的支持是我創作的動力,希望今後能帶給大家更多優質的文章