1. 程式人生 > >flask中celery介紹及使用celery實現非同步任務

flask中celery介紹及使用celery實現非同步任務

Celery簡介
除Celery是一個非同步任務的排程工具。 Celery 是 Distributed Task Queue,分散式任務佇列,分散式決定了可以有多個 worker 的存在,隊列表示其是非同步操作,即存在一個產生任務提出需求的工頭,和一群等著被分配工作的碼農。
Broker
在 Python 中定義 Celery 的時候,我們要引入 Broker(訊息中介軟體),中文翻譯過來就是“中間人”的意思,在這裡 Broker 起到一箇中間人的角色。在工頭提出任務的時候,把所有的任務放到 Broker 裡面,在 Broker 的另外一頭,一群碼農等著取出一個個任務準備著手做。
Backend


這種模式註定了整個系統會是個開環系統,工頭對於碼農們把任務做的怎樣是不知情的。所以我們要引入 Backend 來儲存每次任務的結果。這個 Backend 有點像我們的 Broker,也是儲存任務的資訊用的,只不過這裡存的是那些任務的返回結果。我們可以選擇只讓錯誤執行的任務返回結果到 Backend,這樣我們取回結果,便可以知道有多少任務執行失敗了。
Celery應用場景
1.你想對100臺機器執行一條批量命令,可能會花很長時間 ,但你不想讓你的程式等著結果返回,而是給你返回 一個任務ID,你過一段時間只需要拿著這個任務id就可以拿到任務執行結果, 在任務執行ing進行時,你可以繼續做其它的事情。
2.你想做一個定時任務,比如每天檢測一下你們所有客戶的資料,如果發現今天 是客戶的生日,就給他發個簡訊祝福

Celery的特點
1.簡單:一單熟悉了celery的工作流程後,配置和使用還是比較簡單的
2.高可用:當任務執行失敗或執行過程中發生連線中斷,celery 會自動嘗試重新執行任務
3.快速:一個單程序的celery每分鐘可處理上百萬個任務
3.靈活: 幾乎celery的各個元件都可以被擴充套件及自定製

Celery工作基本流程
這裡寫圖片描述

Celery的安裝
在flask中,開啟終端直接執行一下命令即可安裝:

pip install celery

因為我們在使用celery的過程中,需要用到redis資料庫,請事先配置好redis資料庫,確保資料庫可以正常使用。

開始使用Celery


看一下程式目錄
這裡寫圖片描述

我們把main.py作為啟動檔案,config.py裡面包含celery的配置資訊,sms目錄下的tasks.py(這個名字不能變,只能是這個)裡面是我們要去執行的任務,這個例子是實現了一個網站註冊介面實現非同步任務給使用者傳送註冊資訊的功能。因為傳送簡訊我們是依託於第三方平臺,當我們需要傳送簡訊的時候,需要向第三方平臺傳送請求與傳遞資料,所以這是一個耗時的操作,我們使用非同步任務來提升使用者的體驗度。
下面就來看一下程式碼:
main.py

#coding:utf-8
from celery import Celery

app=Celery("ihome")
app.config_from_object("ihome.tasks.config")
#讓celery自己找到任務
app.autodiscover_tasks(["ihome.tasks.sms"])

config.py

#coding:utf-8
#配置worker
BROKER_URL="redis://127.0.0.1:6379/5"
#配置backend
CELERY_RESULT_BACKEND="redis://127.0.0.1:6379/6"

tasks.py

#coding:utf-8
from celery import Celery

from ihome.libs.yuntongxun.sms import CCP

#建立celery物件
app=Celery("ihome",broker="redis://127.0.0.1:6379/5")

#定義任務
@app.task
def send_template_sms(to,datas,temp_id):
    '''傳送簡訊'''
    #呼叫第三方平臺傳送簡訊程式
    ccp=CCP()
    ret=ccp.sendTemplateSMS(to,datas,temp_id)
    return ret

在我們後端程式中,在需要傳送簡訊的地方使用以下語句:

tasks.send_template_sms.delay(mobile,[sms_code, str(constants.SMS_CODE_REDIS_EXPIRES / 60)],1)

delay裡面的引數可以根據你使用的第三方平臺來確定。