天天看點

Celery學習筆記—快速入門(一)1.快速入門

問題抛出

我們在做網站後端程式開發時,會碰到這樣的需求:使用者需要在我們的網站填寫注冊資訊,我們發給使用者一封注冊激活郵件到使用者郵箱,如果由于各種原因,這封郵件發送所需時間較長,那麼用戶端将會等待很久,造成不好的使用者體驗.
Celery學習筆記—快速入門(一)1.快速入門
那麼怎麼解決這樣的問題呢?
Celery學習筆記—快速入門(一)1.快速入門
Celery學習筆記—快速入門(一)1.快速入門
我們将耗時任務放到背景異步執行。不會影響使用者其他操作。除了注冊功能,例如上傳,圖形處理等等耗時的任務,都可以按照這種思路來解決。 如何實作異步執行任務呢?我們可使用celery. celery除了剛才所涉及到的異步執行任務之外,還可以實作定時處理某些任務。

celery介紹

Celery是一個功能完備即插即用的任務隊列。它使得我們不需要考慮複雜的問題,使用非常簡單。celery看起來似乎很龐大,本章節我們先對其進行簡單的了解,然後再去學習其他一些進階特性。 celery适用異步處理問題,當發送郵件、或者檔案上傳, 圖像處理等等一些比較耗時的操作,我們可将其異步執行,這樣使用者不需要等待很久,提高使用者體驗。 celery的特點是:
  • 簡單,易于使用和維護,有豐富的文檔。
  • 高效,單個celery程序每分鐘可以處理數百萬個任務。
  • 靈活,celery中幾乎每個部分都可以自定義擴充。
celery非常易于內建到一些web開發架構中.

1.快速入門

1.1 Task Queue

  任務隊列是一種跨線程、跨機器工作的一種機制.

  任務隊列中包含稱作任務的工作單元。有專門的工作程序持續不斷的監視任務隊列,并從中獲得新的任務并處理.

  celery通過消息進行通信,通常使用一個叫Broker(中間人)來協client(任務的發出者)和worker(任務的處理者). clients發出消息到隊列中,broker将隊列中的資訊派發給worker來處理。

  一個celery系統可以包含很多的worker和broker,可增強橫向擴充性和高可用性能。

Celery學習筆記—快速入門(一)1.快速入門

舉個栗子:

Celery學習筆記—快速入門(一)1.快速入門
Celery學習筆記—快速入門(一)1.快速入門

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
           

顯示效果如下: 

Celery學習筆記—快速入門(一)1.快速入門

2.調用任務

  任務加入到broker隊列中,以便剛才我們建立的celery workder伺服器能夠從隊列中取出任務并執行。如何将任務函數加入到隊列中,可使用delay()。

進入python終端, 執行如下代碼:

from tasks import my_task
my_task.delay()
           

執行效果如下: 

Celery學習筆記—快速入門(一)1.快速入門

  我們通過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作為結果存儲,并将任務函數修改為兩個參數,并且有傳回值。 

Celery學習筆記—快速入門(一)1.快速入門

更多關于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