異步任務(wù)隊(duì)列Celery在Django中的使用方法
前段時(shí)間在Django Web平臺(tái)開發(fā)中,碰到一些請求執(zhí)行的任務(wù)時(shí)間較長(幾分鐘),為了加快用戶的響應(yīng)時(shí)間,因此決定采用異步任務(wù)的方式在后臺(tái)執(zhí)行這些任務(wù)。在同事的指引下接觸了Celery這個(gè)異步任務(wù)隊(duì)列框架,鑒于網(wǎng)上關(guān)于Celery和Django結(jié)合的文檔較少,大部分也只是粗粗介紹了大概的流程,在實(shí)踐過程中還是遇到了不少坑,希望記錄下來幫助有需要的朋友。
一、Django中的異步請求
Django Web中從一個(gè)http請求發(fā)起,到獲得響應(yīng)返回html頁面的流程大致如下:http請求發(fā)起 -- http handling(request解析) -- url mapping(url正則匹配找到對應(yīng)的View) -- 在View中進(jìn)行邏輯的處理、數(shù)據(jù)計(jì)算(包括調(diào)用Model類進(jìn)行數(shù)據(jù)庫的增刪改查)--將數(shù)據(jù)推送到template,返回對應(yīng)的template/response。

圖1. Django架構(gòu)總覽
同步請求:所有邏輯處理、數(shù)據(jù)計(jì)算任務(wù)在View中處理完畢后返回response。在View處理任務(wù)時(shí)用戶處于等待狀態(tài),直到頁面返回結(jié)果。
異步請求:View中先返回response,再在后臺(tái)處理任務(wù)。用戶無需等待,可以繼續(xù)瀏覽網(wǎng)站。當(dāng)任務(wù)處理完成時(shí),我們可以再告知用戶。
二、關(guān)于Celery
Celery是基于Python開發(fā)的一個(gè)分布式任務(wù)隊(duì)列框架,支持使用任務(wù)隊(duì)列的方式在分布的機(jī)器/進(jìn)程/線程上執(zhí)行任務(wù)調(diào)度。

圖2. Celery架構(gòu)
圖2展示的是Celery的架構(gòu),它采用典型的生產(chǎn)生-消費(fèi)者模式,主要由三部分組成:broker(消息隊(duì)列)、workers(消費(fèi)者:處理任務(wù))、backend(存儲(chǔ)結(jié)果)。實(shí)際應(yīng)用中,用戶從Web前端發(fā)起一個(gè)請求,我們只需要將請求所要處理的任務(wù)丟入任務(wù)隊(duì)列broker中,由空閑的worker去處理任務(wù)即可,處理的結(jié)果會(huì)暫存在后臺(tái)數(shù)據(jù)庫backend中。我們可以在一臺(tái)機(jī)器或多臺(tái)機(jī)器上同時(shí)起多個(gè)worker進(jìn)程來實(shí)現(xiàn)分布式地并行處理任務(wù)。
三、Django中Celery的實(shí)現(xiàn)
在實(shí)際使用過程中,發(fā)現(xiàn)在Celery在Django里的實(shí)現(xiàn)與其在一般.py文件中的實(shí)現(xiàn)還是有很大差別,Django有其特定的使用Celery的方式。這里著重介紹Celery在Django中的實(shí)現(xiàn)方法,簡單介紹與其在一般.py文件中實(shí)現(xiàn)方式的差別。
1. 建立消息隊(duì)列
首先,我們必須擁有一個(gè)broker消息隊(duì)列用于發(fā)送和接收消息。Celery官網(wǎng)給出了多個(gè)broker的備選方案:RabbitMQ、Redis、Database(不推薦)以及其他的消息中間件。在官網(wǎng)的強(qiáng)力推薦下,我們就使用RabbitMQ作為我們的消息中間人。在Linux上安裝的方式如下:
sudo apt-get install rabbitmq-server
命令執(zhí)行成功后,rabbitmq-server就已經(jīng)安裝好并運(yùn)行在后臺(tái)了。
另外也可以通過命令rabbitmq-server來啟動(dòng)rabbitmq server以及命令rabbitmqctl stop來停止server。
更多的命令可以參考rabbitmq官網(wǎng)的用戶手冊: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//'
其中,當(dāng)djcelery.setup_loader()運(yùn)行時(shí),Celery便會(huì)去查看INSTALLD_APPS下包含的所有app目錄中的tasks.py文件,找到標(biāo)記為task的方法,將它們注冊為celery task。BROKER_URL和CELERY_RESULT_BACKEND分別指代你的Broker的代理地址以及Backend(result store)數(shù)據(jù)存儲(chǔ)地址。在Django中如果沒有設(shè)置backend,會(huì)使用其默認(rèn)的后臺(tái)數(shù)據(jù)庫用來存儲(chǔ)數(shù)據(jù)。注意,此處backend的設(shè)置是通過關(guān)鍵字CELERY_RESULT_BACKEND來配置,與一般的.py文件中實(shí)現(xiàn)celery的backend設(shè)置方式有所不同。一般的.py中是直接通過設(shè)置backend關(guān)鍵字來配置,如下所示:
app = Celery('tasks', backend='amqp://guest@localhost//', broker='amqp://guest@localhost//')
然后,在INSTALLED_APPS中加入djcelery:
INSTALLED_APPS = ( …… 'qv', 'djcelery' …… )
4. 在要使用該任務(wù)隊(duì)列的app根目錄下(比如qv),建立tasks.py,比如:

在tasks.py中我們就可以編碼實(shí)現(xiàn)我們需要執(zhí)行的任務(wù)邏輯,在開始處import task,然后在要執(zhí)行的任務(wù)方法開頭用上裝飾器@task。需要注意的是,與一般的.py中實(shí)現(xiàn)celery不同,tasks.py必須建在各app的根目錄下,且不能隨意命名。
5. 生產(chǎn)任務(wù)
在需要執(zhí)行該任務(wù)的View中,通過build_job.delay的方式來創(chuàng)建任務(wù),并送入消息隊(duì)列。比如:

6. 啟動(dòng)worker的命令
#先啟動(dòng)服務(wù)器 python manage.py runserver #再啟動(dòng)worker python manage.py celery worker -c 4 --loglevel=info
四、補(bǔ)充
Django下要查看其他celery的命令,包括參數(shù)配置、啟動(dòng)多worker進(jìn)程的方式都可以通過python manage.py celery --help來查看:

另外,Celery提供了一個(gè)工具flower,將各個(gè)任務(wù)的執(zhí)行情況、各個(gè)worker的健康狀態(tài)進(jìn)行監(jiān)控并以可視化的方式展現(xiàn),如下圖所示:

Django下實(shí)現(xiàn)的方式如下:
1. 安裝flower:
pip install flower
2. 啟動(dòng)flower(默認(rèn)會(huì)啟動(dòng)一個(gè)webserver,端口為5555):
python manage.py celery flower
3. 進(jìn)入http://localhost:5555即可查看。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python標(biāo)準(zhǔn)庫中的sys你了解嗎
這篇文章主要為大家詳細(xì)介紹了Python標(biāo)準(zhǔn)庫中的sys,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03
Python的子線程和子進(jìn)程是如何手動(dòng)結(jié)束的?
今天給大家?guī)淼氖顷P(guān)于Python的相關(guān)知識(shí),文章圍繞著如何手動(dòng)結(jié)束Python的子線程和子進(jìn)程展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
python畫圖時(shí)給圖中的點(diǎn)加標(biāo)簽和plt.text的使用
這篇文章主要介紹了python畫圖時(shí)給圖中的點(diǎn)加標(biāo)簽和plt.text的使用,利用matplotlib模塊畫各城市2019-nCoV疫情確診人數(shù)和節(jié)前流入人口數(shù)的圖的時(shí)候遇到了要給圖中的點(diǎn)加上標(biāo)簽示意,需要的朋友可以參考一下2022-03-03
Python實(shí)現(xiàn)一鍵整理百度云盤中重復(fù)無用文件
有沒有頭疼過百度云盤都要塞滿了,可是又沒有工具能剔除大量重復(fù)無用的文件?這里教你一個(gè)用Python實(shí)現(xiàn)的簡單方法,通過整理目錄的方式來處理我們云盤中無用的文件吧2022-08-08
python數(shù)據(jù)庫操作常用功能使用詳解(創(chuàng)建表/插入數(shù)據(jù)/獲取數(shù)據(jù))
這篇文章主要介紹了python數(shù)據(jù)庫操作常用功能使用方法:獲取mysql版本、創(chuàng)建表、插入數(shù)據(jù)、slect獲取數(shù)據(jù)等,下面看示例吧2013-12-12
conda創(chuàng)建環(huán)境過程出現(xiàn)"Solving?environment:?failed"報(bào)錯(cuò)的詳細(xì)解
很長一段時(shí)間沒用conda了,然后突然使用conda創(chuàng)建環(huán)境報(bào)錯(cuò),所以下面這篇文章主要給大家介紹了關(guān)于conda創(chuàng)建環(huán)境過程出現(xiàn)"Solving?environment:?failed"報(bào)錯(cuò)的詳細(xì)解決方法,需要的朋友可以參考下2022-11-11
python自動(dòng)化測試之異常及日志操作實(shí)例分析
這篇文章主要介紹了python自動(dòng)化測試之異常及日志操作,結(jié)合實(shí)例形式分析了python自動(dòng)化測試中的異常捕獲與日志記錄相關(guān)操作技巧,需要的朋友可以參考下2019-11-11
python樹的雙親存儲(chǔ)結(jié)構(gòu)的實(shí)現(xiàn)示例
本文主要介紹了python樹的雙親存儲(chǔ)結(jié)構(gòu),這種存儲(chǔ)結(jié)構(gòu)是一種順序存儲(chǔ)結(jié)構(gòu),采用元素形如“[結(jié)點(diǎn)值,雙親結(jié)點(diǎn)索引]”的列表表示,感興趣的可以了解一下2023-11-11

