問題抛出
我們在做網站後端程式開發時,會碰到這樣的需求:使用者需要在我們的網站填寫注冊資訊,我們發給使用者一封注冊激活郵件到使用者郵箱,如果由于各種原因,這封郵件發送所需時間較長,那麼用戶端将會等待很久,造成不好的使用者體驗.那麼怎麼解決這樣的問題呢?![]()
Celery學習筆記—快速入門(一)1.快速入門 ![]()
Celery學習筆記—快速入門(一)1.快速入門 我們将耗時任務放到背景異步執行。不會影響使用者其他操作。除了注冊功能,例如上傳,圖形處理等等耗時的任務,都可以按照這種思路來解決。 如何實作異步執行任務呢?我們可使用celery. celery除了剛才所涉及到的異步執行任務之外,還可以實作定時處理某些任務。![]()
Celery學習筆記—快速入門(一)1.快速入門
celery介紹
Celery是一個功能完備即插即用的任務隊列。它使得我們不需要考慮複雜的問題,使用非常簡單。celery看起來似乎很龐大,本章節我們先對其進行簡單的了解,然後再去學習其他一些進階特性。 celery适用異步處理問題,當發送郵件、或者檔案上傳, 圖像處理等等一些比較耗時的操作,我們可将其異步執行,這樣使用者不需要等待很久,提高使用者體驗。 celery的特點是:celery非常易于內建到一些web開發架構中.
- 簡單,易于使用和維護,有豐富的文檔。
- 高效,單個celery程序每分鐘可以處理數百萬個任務。
- 靈活,celery中幾乎每個部分都可以自定義擴充。
1.快速入門
1.1 Task Queue
任務隊列是一種跨線程、跨機器工作的一種機制.
任務隊列中包含稱作任務的工作單元。有專門的工作程序持續不斷的監視任務隊列,并從中獲得新的任務并處理.
celery通過消息進行通信,通常使用一個叫Broker(中間人)來協client(任務的發出者)和worker(任務的處理者). clients發出消息到隊列中,broker将隊列中的資訊派發給worker來處理。
一個celery系統可以包含很多的worker和broker,可增強橫向擴充性和高可用性能。
舉個栗子:
1.2Celery安裝
我們可以使用python的包管理器pip來安裝:
pip install -U Celery
也可從官方直接下載下傳安裝包:https://pypi.python.org/pypi/celery/
tar xvfz celery-0.0.0.tar.gz
cd celery-0.0.0
python setup.py build
python setup.py install
1.3Broker
Celery需要一種解決消息的發送和接受的方式,我們把這種用來存儲消息的的中間裝置叫做message broker, 也可叫做消息中間人。 作為中間人,我們有幾種方案可選擇:
1.RabbitMQ
RabbitMQ是一個功能完備,穩定的并且易于安裝的broker. 它是生産環境中最優的選擇。使用RabbitMQ的細節參照以下連結: http://docs.celeryproject.org/en/latest/getting-started/brokers/rabbitmq.html#broker-rabbitmq
如果我們使用的是Ubuntu或者Debian發行版的Linux,可以直接通過下面的指令安裝RabbitMQ: sudo apt-get install rabbitmq-server 安裝完畢之後,RabbitMQ-server伺服器就已經在背景運作。如果您用的并不是Ubuntu或Debian, 可以在以下網址: http://www.rabbitmq.com/download.html 去查找自己所需要的版本軟體。
2.Redis
Redis也是一款功能完備的broker可選項,但是其更可能因意外中斷或者電源故障導緻資料丢失的情況。 關于是有那個Redis作為Broker,可訪下面網址: http://docs.celeryproject.org/en/latest/getting-started/brokers/redis.html#broker-redis
1.4Application
使用celery第一件要做的最為重要的事情是需要先建立一個Celery執行個體,我們一般叫做celery應用,或者更簡單直接叫做一個app。app應用是我們使用celery所有功能的入口,比如建立任務,管理任務等,在使用celery的時候,app必須能夠被其他的子產品導入。
1.建立應用
我們首先建立tasks.py子產品, 其内容為:
from celery import Celery
# 我們這裡案例使用redis作為broker
app = Celery('demo', broker='redis://:[email protected]/1')
# 建立任務函數
@app.task
def my_task():
print("任務函數正在執行....")
Celery第一個參數是給其設定一個名字, 第二參數我們設定一個中間人broker, 在這裡我們使用Redis作為中間人。my_task函數是我們編寫的一個任務函數, 通過加上裝飾器app.task, 将其注冊到broker的隊列中。
現在我們在建立一個worker, 等待處理隊列中的任務.打開終端,cd到tasks.py同級目錄中,執行指令:
celery -A tasks worker --loglevel=info
顯示效果如下:
2.調用任務
任務加入到broker隊列中,以便剛才我們建立的celery workder伺服器能夠從隊列中取出任務并執行。如何将任務函數加入到隊列中,可使用delay()。
進入python終端, 執行如下代碼:
from tasks import my_task
my_task.delay()
執行效果如下:
我們通過worker的控制台,可以看到我們的任務被worker處理。調用一個任務函數,将會傳回一個AsyncResult對象,這個對象可以用來檢查任務的狀态或者獲得任務的傳回值。
3.存儲結果
如果我們想跟蹤任務的狀态,Celery需要将結果儲存到某個地方。有幾種儲存的方案可選:SQLAlchemy、Django ORM、Memcached、 Redis、RPC (RabbitMQ/AMQP)。
例子我們仍然使用Redis作為存儲結果的方案,任務結果存儲配置我們通過Celery的backend參數來設定。我們将tasks子產品修改如下:
from celery import Celery
# 我們這裡案例使用redis作為broker
app = Celery('demo',
backend='redis://:[email protected]:6379/2',
broker='redis://:[email protected]:6379/1')
# 建立任務函數
@app.task
def my_task(a, b):
print("任務函數正在執行....")
return a + b
我們給Celery增加了backend參數,指定redis作為結果存儲,并将任務函數修改為兩個參數,并且有傳回值。
更多關于result對象資訊,請參閱下列網址:http://docs.celeryproject.org/en/latest/reference/celery.result.html#module-celery.result
1.5配置
Celery使用簡單,配置也非常簡單。Celery有很多配置選項能夠使得celery能夠符合我們的需要,但是預設的幾項配置已經足夠應付大多數應用場景了。
配置資訊可以直接在app中設定,或者通過專有的配置子產品來配置。
1.直接通過app來配置
from celery import Celery
app = Celery('demo')
# 增加配置
app.conf.update(
result_backend='redis://:[email protected]:6379/2',
broker_url='redis://:[email protected]:6379/1',
)
2.專有配置檔案
對于比較大的項目,我們建議配置資訊作為一個單獨的子產品。我們可以通過調用app的函數來告訴Celery使用我們的配置子產品。
配置子產品的名字我們取名為celeryconfig, 這個名字不是固定的,我們可以任意取名,建議這麼做。我們必須保證配置子產品能夠被導入。 配置子產品的名字我們取名為celeryconfig, 這個名字不是固定的,我們可以任意取名,建議這麼做。我們必須保證配置子產品能夠被導入。
下面我們在tasks.py子產品 同級目錄下建立配置子產品celeryconfig.py:
result_backend = 'redis://:[email protected]:6379/2'
broker_url = 'redis://:[email protected]:6379/1'
tasks.py檔案修改為:
from celery import Celery
import celeryconfig
# 我們這裡案例使用redis作為broker
app = Celery('demo')
# 從單獨的配置子產品中加載配置
app.config_from_object('celeryconfig')
更多配置: http://docs.celeryproject.org/en/latest/userguide/configuration.html#configuration