寫作背景介紹
最近在做后台圖像處理,需要使用到celery
這個異步任務框架。但是使用的時候遇到很多技術問題,為了方便日后再遇到相似問題時能夠快速解決。寫下這篇文章也希望能夠幫助共同奮戰在同一戰線的程序員們。這篇是入門級的文章,如果你已經使用過celery開發過項目完全可以忽略它。當然也非常歡迎你給我留下你寶貴的意見。下一篇文章將會深入一點,期待能再次看到你。
Celery環境搭建
celery是異步處理框架,我們需要一個消息隊列來下發我們的任務。使用RabbitMQ是官方特別推薦的方式,因此我也使用它作為我們的broker
安裝rabbitmq
我使用的是linuxmint系統,如果是你使用的是ubuntu或者其他的操作系統可以在官網找到安裝方案。
sudo apt-get install rabbitmq-server
安裝celery
Celery可以通過pip
自動安裝,如果你喜歡使用虛擬環境安裝可以先使用virtualenv
創建一個自己的虛擬環境。反正我喜歡使用virtualenv
建立自己的環境。
pip install -U celery
第一個例子
按照編程的慣例,我們先設計一個hello world示例。
第一步
編寫簡單的純python函數
def say(x,y):
return x+y
if __name__ == '__main__':
say('Hello','World')
第二步
如果這個函數不是簡單的輸出兩個字符串相加,而是需要查詢數據庫或者進行復雜的處理。這種處理需要耗費大量的時間,還是這種方式執行會是多么糟糕的事情。為了演示這種現象,可以使用sleep
函數來模擬高耗時任務。
import time
def say(x,y):
time.sleep(5)
return x+y
if __name__ == '__main__':
say('Hello','World')
第三步
這時候我們可能會思考怎么使用多進程或者多線程去實現這種任務。對於多進程與多線程的不足這里不做討論。現在我們可以想想celery
到底能不能解決這種問題。
import time
from celery import Celery
app = Celery('sample',broker='amqp://guest@localhost//')
@app.task
def say(x,y):
time.sleep(5)
return x+y
if __name__ == '__main__':
say('Hello','World')
現在來解釋一下新加入的幾行代碼,首先說明一下加入的新代碼完全不需要改變原來的代碼。導入celery模塊就不用解釋了,聲明一個celery
實例app
的參數需要解釋一下。
- 第一個參數是這個
python
文件的名字,注意到我們已經把.py
去掉了。 - 第二個參數是用到了我們的rabbitmq隊列啦!可以看到其使用的方式非常簡單,因為它是默認的消息隊列端口號都不需要指明。
第四步
現在我們已經使用了celery框架了,我們需要讓它找幾個工人幫我們干活。好現在就讓他們干活。
celery -A sample worker --loglevel=info
這條命令有些長,我來解釋一下吧。
-A
代表的是Application的首字母,我們的應用就是在sample里面呢。worker
就是我們的工人了,他們會努力完成我們的工作的。-loglevel=info
指明了我們的工作后台執行情況,雖然工人們已經向你保證過一定努力完成任務。但是謹慎的你還是希望看看工作進展情況。
回車后你可以看到類似下面這樣一個輸出,如果是沒有紅色的輸出那么你應該是沒有遇到什么錯誤的。
第五步
現在我們的任務已經被加載到了內存中,我們不能再想之前那樣執行python sample.py
來運行程序了。我們可以通過終端起到python
然后通過下面的方式加載任務。
python
輸入python
語句
from sample import say
say.delay('hello','world')
我們的函數會立即返回,不需要等待。就那么簡單celery
解決了我們的問題。可以發現我們的say
函數不是直接調用了,它被celery
的task
裝飾器修飾過了。所以多了一些屬性。目前我們只需要知道使用delay
就行了。
第六步
看看我的結果吧!
可憐的我們會發現結果輸出在另一個終端上不是我們調用say.delay
的終端上。這其實是正常的,因為我們的工作已經交給后台去處理了。
總結
現在,我們知道celery的確可以在后台完成我們交給它的任務。只不過它脾氣我們還沒摸透。為什么干完事了沒有告訴我們,讓我們在任務發布終端等了好久。還有就是celery
配置在工作函數say
一個文件中總是讓我們感覺不爽。這些問題我們下一篇文章將會解決它,看看celery
到底多強大。