異步任務(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。

image
                     圖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)度。

image

圖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)(本文使用Django2.0十办,celery3.1版本)

在實(shí)際使用過程中秀撇,發(fā)現(xiàn)在Celery在Django里的實(shí)現(xiàn)與其在一般.py文件中的實(shí)現(xiàn)還是有很大差別,Django有其特定的使用Celery的方式向族。這里著重介紹Celery在Django中的實(shí)現(xiàn)方法呵燕,在一般.py文件中實(shí)現(xiàn)方式可查看http://www.reibang.com/p/0f3f377384ab

1件相、安裝依賴包
pip install django-celery
pip install celery-with-redis
2再扭、配置settings
import djcelery
# 注冊djcelery應(yīng)用
INSTALLED_APPS = (
...
'djcelery' 
)

"""celery配置"""
djcelery.setup_loader()
# celery 中間人設(shè)置
BROKER_URL = 'redis://localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'

# celery內(nèi)容等消息的格式設(shè)置
CELERY_ACCEPT_CONTENT = ['application/json', ]
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'

# 任務(wù)限制
CELERYD_CONCURRENCY = 20  # 并發(fā)worker數(shù)
CELERYD_MAX_TASKS_PER_CHILD = 100    # 每個(gè)worker最多執(zhí)行萬100個(gè)任務(wù)就會(huì)被銷      毀,可防止內(nèi)存泄露

# celery時(shí)區(qū)設(shè)置夜矗,使用settings中TIME_ZONE同樣的時(shí)區(qū)
CELERY_TIMEZONE = TIME_ZONE
3泛范、在django 根目錄下新建celery.py配置文件
from __future__ import absolute_import
from celery import Celery
import os
from django.conf import settings

project_name = os.path.split(os.path.abspath('.'))[-1]
project_settings = '%s.settings' % project_name
# 設(shè)置環(huán)境變量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)
# 實(shí)例化Celery
app = Celery(project_name)

# 使用django的settings文件配置celery
app.config_from_object('django.conf:settings')

# Celery加載所有注冊的應(yīng)用
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)

CELERY_ACCEPT_CONTENT = ['pickle']

@app.task(bind=True)
def debug_task(self):
      print('Request: {0!r}'.format(self.request))
4、在Django根目錄下init.py下添加
from .celery import app as celery_app
__all__ = ('celery_app',)
5紊撕、在將要使用異步加載的APP下新建tasks.py
# 從自己的項(xiàng)目中導(dǎo)入celery_app罢荡,WechatProject是我自己的項(xiàng)目名
from WechatProject import celery_app
  
 # 將耗時(shí)的函數(shù)標(biāo)記為task 
 @celery_app.task
 def crawl(u):
     .......

其中,當(dāng)djcelery.setup_loader()運(yùn)行時(shí),Celery便會(huì)去查看INSTALLD_APPS下包含的所有app目錄中的tasks.py文件柠傍,找到標(biāo)記為task的方法麸俘,將它們注冊為celery task。

6惧笛、views調(diào)用異步任務(wù)
from .tasks import crawl

# 執(zhí)行異步任務(wù)
r = crawl.delay(u)
7从媚、啟動(dòng)Django、查看celery woker輸入日志患整、啟動(dòng)心跳執(zhí)行定時(shí)任務(wù)(每次更改定時(shí)時(shí)間拜效,都要執(zhí)行 python manage.py celery beat ,才能生效)
python manage.py runserver
python manage.py celery worker -l info
python manage.py celery beat 

希望能幫助正在學(xué)習(xí)celery的你各谚,如有問題歡迎指出~本文部分參考https://www.cnblogs.com/znicy/p/5626040.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末紧憾,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子昌渤,更是在濱河造成了極大的恐慌赴穗,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膀息,死亡現(xiàn)場離奇詭異般眉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)潜支,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門甸赃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冗酿,你說我怎么就攤上這事埠对。” “怎么了裁替?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵项玛,是天一觀的道長。 經(jīng)常有香客問我弱判,道長稍计,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任裕循,我火速辦了婚禮,結(jié)果婚禮上净刮,老公的妹妹穿的比我還像新娘剥哑。我一直安慰自己,他們只是感情好淹父,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布株婴。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪困介。 梳的紋絲不亂的頭發(fā)上大审,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音座哩,去河邊找鬼徒扶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛根穷,可吹牛的內(nèi)容都是我干的姜骡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼屿良,長吁一口氣:“原來是場噩夢啊……” “哼圈澈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尘惧,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對情侶失蹤康栈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后喷橙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啥么,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年重慢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饥臂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡似踱,死狀恐怖隅熙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情核芽,我是刑警寧澤囚戚,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站轧简,受9級(jí)特大地震影響驰坊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜哮独,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一拳芙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧皮璧,春花似錦舟扎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春羡疗,著一層夾襖步出監(jiān)牢的瞬間染服,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國打工叨恨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柳刮,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓特碳,卻偏偏與公主長得像诚亚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子午乓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容