異步任務隊列Celery在Django中的使用

前段時間在Django Web平臺開發中,碰到一些請求執行的任務時間較長(幾分鐘),爲了加快用戶的響應時間,所以決定採用異步任務的方式在後臺執行這些任務。在同事的指引下接觸了Celery這個異步任務隊列框架,鑑於網上關於Celery和Django結合的文檔較少,大部分也只是粗粗介紹了大概的流程,在實踐過程當中仍是遇到了很多坑,但願記錄下來幫助有須要的朋友。html

1、Django中的異步請求

Django Web中從一個http請求發起,到得到響應返回html頁面的流程大體以下:http請求發起 -- http handling(request解析) -- url mapping(url正則匹配找到對應的View) -- 在View中進行邏輯的處理、數據計算(包括調用Model類進行數據庫的增刪改查)--將數據推送到template,返回對應的template/response。前端

                         圖1. Django架構總覽python

同步請求:全部邏輯處理、數據計算任務在View中處理完畢後返回response。在View處理任務時用戶處於等待狀態,直到頁面返回結果。web

異步請求:View中先返回response,再在後臺處理任務。用戶無需等待,能夠繼續瀏覽網站。當任務處理完成時,咱們能夠再告知用戶。數據庫

2、關於Celery

  Celery是基於Python開發的一個分佈式任務隊列框架,支持使用任務隊列的方式在分佈的機器/進程/線程上執行任務調度。django

            圖2. Celery架構服務器

  圖2展現的是Celery的架構,它採用典型的生產生-消費者模式,主要由三部分組成:broker(消息隊列)、workers(消費者:處理任務)、backend(存儲結果)。實際應用中,用戶從Web前端發起一個請求,咱們只須要將請求所要處理的任務丟入任務隊列broker中,由空閒的worker去處理任務便可,處理的結果會暫存在後臺數據庫backend中。咱們能夠在一臺機器或多臺機器上同時起多個worker進程來實現分佈式地並行處理任務。架構

3、Django中Celery的實現

  在實際使用過程當中,發如今Celery在Django裏的實現與其在通常.py文件中的實現仍是有很大差異,Django有其特定的使用Celery的方式。這裏着重介紹Celery在Django中的實現方法,簡單介紹與其在通常.py文件中實現方式的差異。app

  1. 創建消息隊列

  首先,咱們必須擁有一個broker消息隊列用於發送和接收消息。Celery官網給出了多個broker的備選方案:RabbitMQ、Redis、Database(不推薦)以及其餘的消息中間件。在官網的強力推薦下,咱們就使用RabbitMQ做爲咱們的消息中間人。在Linux上安裝的方式以下:框架

sudo apt-get install rabbitmq-server

  命令執行成功後,rabbitmq-server就已經安裝好並運行在後臺了。

  另外也能夠經過命令rabbitmq-server來啓動rabbitmq server以及命令rabbitmqctl stop來中止server。

  更多的命令能夠參考rabbitmq官網的用戶手冊:https://www.rabbitmq.com/manpages.html

  2. 安裝django-celery

pip install celery
pip install django-celery

  3. 配置settings.py

  首先,在Django工程的settings.py文件中加入以下配置代碼:

import djcelery
djcelery.setup_loader()
BROKER_URL= 'amqp://guest@localhost//'
CELERY_RESULT_BACKEND = 'amqp://guest@localhost//'

  其中,當djcelery.setup_loader()運行時,Celery便會去查看INSTALLD_APPS下包含的全部app目錄中的tasks.py文件,找到標記爲task的方法,將它們註冊爲celery task。BROKER_URL和CELERY_RESULT_BACKEND分別指代你的Broker的代理地址以及Backend(result store)數據存儲地址。在Django中若是沒有設置backend,會使用其默認的後臺數據庫用來存儲數據。注意,此處backend的設置是經過關鍵字CELERY_RESULT_BACKEND來配置,與通常的.py文件中實現celery的backend設置方式有所不一樣。通常的.py中是直接經過設置backend關鍵字來配置,以下所示:

app = Celery('tasks', backend='amqp://guest@localhost//', broker='amqp://guest@localhost//')

  而後,在INSTALLED_APPS中加入djcelery:

INSTALLED_APPS = (
    ……   
'qv', 'djcelery' …… )

  4. 在要使用該任務隊列的app根目錄下(好比qv),創建tasks.py,好比:

  在tasks.py中咱們就能夠編碼實現咱們須要執行的任務邏輯,在開始處import task,而後在要執行的任務方法開頭用上裝飾器@task。須要注意的是,與通常的.py中實現celery不一樣,tasks.py必須建在各app的根目錄下,且不能隨意命名。

  5. 生產任務

  在須要執行該任務的View中,經過build_job.delay的方式來建立任務,並送入消息隊列。好比:

  6. 啓動worker的命令

#先啓動服務器
python manage.py runserver
#再啓動worker 
python manage.py celery worker -c 4 --loglevel=info

4、補充

  Django下要查看其餘celery的命令,包括參數配置、啓動多worker進程的方式均可以經過python manage.py celery --help來查看:

   另外,Celery提供了一個工具flower,將各個任務的執行狀況、各個worker的健康狀態進行監控並以可視化的方式展示,以下圖所示:

  Django下實現的方式以下: 

  1. 安裝flower:

pip install flower

  2. 啓動flower(默認會啓動一個webserver,端口爲5555):

python manage.py celery flower

  3. 進入http://localhost:5555便可查看。

相關文章
相關標籤/搜索