異步方案Celery
生產(chǎn)者消費者設(shè)計模式
問題:
我們的代碼是自上而下同步執(zhí)行的。
發(fā)送短信是耗時的操作。如果短信被阻塞住,用戶響應(yīng)將會延遲。
響應(yīng)延遲會造成用戶界面的倒計時延遲。
解決:
異步發(fā)送短信
發(fā)送短信和響應(yīng)分開執(zhí)行,將發(fā)送短信從主業(yè)務(wù)中解耦出來。
生產(chǎn)者消費者設(shè)計模式介紹
為了將發(fā)送短信從主業(yè)務(wù)中解耦出來,我們引入生產(chǎn)者消費者設(shè)計模式。
它是最常用的解耦方式之一,尋找中間人(broker)搭橋,保證兩個業(yè)務(wù)沒有直接關(guān)聯(lián)。
總結(jié):
生產(chǎn)者生成消息,緩存到消息隊列中,消費者讀取消息隊列中的消息并執(zhí)行。
由商城生成發(fā)送短信消息,緩存到消息隊列中,消費者讀取消息隊列中的發(fā)送短信消息并執(zhí)行。
Celery介紹和使用
消費者取到消息之后,要消費掉(執(zhí)行任務(wù)),需要我們?nèi)崿F(xiàn)。
任務(wù)可能出現(xiàn)高并發(fā)的情況,需要補充多任務(wù)的方式執(zhí)行。
耗時任務(wù)很多種,每種耗時任務(wù)編寫的生產(chǎn)者和消費者代碼有重復(fù)。
取到的消息什么時候執(zhí)行,以什么樣的方式執(zhí)行。
結(jié)論:
實際開發(fā)中,我們可以借助成熟的工具Celery來完成。
有了Celery,我們在使用生產(chǎn)者消費者模式時,只需要關(guān)注任務(wù)本身,極大的簡化了程序員的開發(fā)流程。
Celery介紹
Celery
。介紹一個簡單、靈活且可靠、處理大量消息的分布式系統(tǒng),可以在一臺或者多臺機器上運行。
。單個 Celery 進程每分鐘可處理數(shù)以百萬計的任務(wù)。
。通過消息進行通信,使用消息隊列(broker)在客戶端和消費者之間進行協(xié)調(diào)。
安裝Celery
1 $ pip install Celery
創(chuàng)建Celery實例并加載配置
celery_tasks.main.py
1 # celery啟動文件
2 from celery import Celery
3 # 創(chuàng)建celery實例
4 celery_app=Celery('home')
加載Celery配置
celery_tasks.config.py
1 # 指定消息隊列的位置
2 broker_url="redis://127.0.0.1/10"
celery_tasks.main.py
1 # celery啟動文件
2 from celery import Celery
3 # 創(chuàng)建celery實例
4 celery_app=Celery('home')
5 # 加載celery配置
6 celery_app.config_from_object('celery_tasks.config')
定義發(fā)送短信任務(wù)
注冊任務(wù):celery_tasks.main.py
1 # celery啟動文件
2 from celery import Celery
3 # 創(chuàng)建celery實例
4 celery_app=Celery('home')
5 # 加載celery配置
6 celery_app.config_from_object('celery_tasks.config')
7 # 自動注冊celery任務(wù)
8 celery_app.autodiscover_tasks(['celery_tasks.sms'])
定義任務(wù):celery_tasks.sms.tasks.py
1 @celery_app.task
2 def send_sms(to,datas,temp_id):
3? ? ? ?"""發(fā)送短信的異步任務(wù)"""
4? ? ? ?ccp = CCP()
5? ? ? ?try:
6? ? ? ? ? ? ?result=ccp.send_message(to,datas,temp_id)
7? ? ? ?except Exception as e:
8? ? ? ? ? ? ?result=-2
9? ? ? ? return result
啟動Celery服務(wù)
1 celery -A home.tasks.task_sms worker -l info
-A指對應(yīng)的應(yīng)用程序, 其參數(shù)是項目中 Celery實例的位置。
worker指這里要啟動的worker。
-l指日志等級,比如info等級。
調(diào)用發(fā)送短信任務(wù)
1# Celery異步發(fā)送短信驗證碼
2send_sms.delay(mobile, [sms_code,int(constants.SMS_CODE_REDIS_EXPIRES/60)]
用戶登錄
賬號登錄
用戶名登錄邏輯分析
用戶名登錄接口設(shè)計
用戶名登錄接口定義
1 @api.route("/sessions", methods=["POST"])
2 def login():
3? ? ? ? """用戶登錄
4? ? ? ? 參數(shù): 手機號、密碼, json
5? ? ? ? """
用戶名登錄后端邏輯
1 @api.route("/sessions", methods=["POST"])
2 def login():
3? ? ? ? """用戶登錄
4? ? ? ? 參數(shù): 手機號、密碼, json
5? ? ? ? """
6? ? ? ? # 獲取參數(shù)
7? ? ? ? # 校驗參數(shù)
8? ? ? ? # 手機號的格式
9? ? ? ? # 從數(shù)據(jù)庫中根據(jù)手機號查詢用戶的數(shù)據(jù)對象
10? ? ? ?# 用數(shù)據(jù)庫的密碼與用戶填寫的密碼進行對比驗證
11? ? ? ? # 如果驗證相同成功,保存登錄狀態(tài), 在session中
2020-11-26