1. pipeline操作Redis資料庫
Redis的 C - S 架構:
? 基于客戶端-服務端模型以及請求/回應協議的TCP服務,
? 客戶端向服務端發送一個查詢請求,并監聽Socket回傳,
? 通常是以阻塞模式,等待服務端回應,
? 服務端處理命令,并將結果回傳給客戶端,
存在的問題:
? 如果Redis服務端需要同時處理多個請求,加上網路延遲,那么服務端利用率不高,效率降低,
解決的辦法:
? 管道pipeline

pipeline的介紹
管道pipeline
? 可以一次性發送多條命令并在執行完后一次性將結果回傳,
? pipeline通過減少客戶端與Redis的通信次數來實作降低往返延時時間,
實作的原理
? 實作的原理是佇列,
? Client可以將三個命令放到一個tcp報文一起發送,
? Server則可以將三條命令的處理結果放到一個tcp報文回傳,
? 佇列是先進先出,這樣就保證資料的順序性,

pipeline操作Redis資料庫
實作步驟
1. 創建Redis管道
2. 將Redis請求添加到佇列
3. 執行請求
@@@ 代碼自行實作,不展示,
2. 生產者消費者設計模式
問題:
? 我們的代碼是自上而下同步執行的,
? 發送短信是耗時的操作,如果短信被阻塞住,用戶回應將會延遲,
? 回應延遲會造成用戶界面的倒計時延遲,

解決:
? 異步發送短信
? 發送短信和回應分開執行,將發送短信從主業務中解耦出來,
生產者消費者設計模式介紹
? 為了將發送短信從主業務中解耦出來,我們引入生產者消費者設計模式,
? 它是最常用的解耦方式之一,尋找中間人(broker)搭橋,保證兩個業務沒有直接關聯,

總結:
? 生產者生成訊息,快取到訊息佇列中,消費者讀取訊息佇列中的訊息并執行,
? 由網站生成發送短信訊息,快取到訊息佇列中,消費者讀取訊息佇列中的發送短信訊息并執行,
3. celery 介紹、安裝和處理
思考:
? 消費者取到訊息之后,要消費掉(執行任務),需要我們去實作,
? 任務可能出現高并發的情況,需要補充多任務的方式執行,
? 耗時任務很多種,每種耗時任務撰寫的生產者和消費者代碼有重復,
? 取到的訊息什么時候執行,以什么樣的方式執行,
結論:
? 實際開發中,我們可以借助成熟的工具Celery來完成,
? 有了Celery,我們在使用生產者消費者模式時,只需要關注任務本身,極大的簡化了程式員的開發流程
Celery介紹
? 一個簡單、靈活且可靠、處理大量訊息的分布式系統,可以在一臺或者多臺機器上運行,
? 單個 Celery 行程每分鐘可處理數以百萬計的任務,
? 通過訊息進行通信,使用訊息佇列(broker)在客戶端和消費者之間進行協調,
安裝celery
不建議安裝最新版本5.0 以上,因為我的redis 版本也不高,否則要同步升高,所以安裝4.4.7即可,
pip install celery==4.4.7 -i https://pypi.douban.com/simple

創建Celery實體并加載配置
step 1 定義包
它可以脫離django使用, 也不必新建再utils 了, 直接在專案包含manage.py的目錄下新建package (celery_tasks), 將來也可以拿走

step 2 創建Celery實體
celery_tasks.main.py
新建main檔案, (相當于celery的入口檔案)
千萬,百萬注意, 我是因為實體化的名字起了跟目錄同名的billshop ,導致異步處理短信未能發送成功,除錯了3小時找到了問題, 基本沒有提示資訊,celery注意了, 后來我起名lg了,
# celery啟動檔案
from celery import Celery
# 創建celery實體
celery_app = Celery('bill')
step 3 加載Celery配置
celery_tasks.config.py
資料庫可以不用連續之前的 0 1 2 .,, 因為以后可能單獨拿走 ,所以我從倒數10資料庫用,
# 指定訊息佇列的位置
broker_url = "redis://127.0.0.1/10"
celery_tasks.main.py
# celery啟動檔案
from celery import Celery
# 創建celery實體
celery_app = Celery('lg')
# 加載celery配置
celery_app.config_from_object('celery_tasks.config')
step 4 定義發送短信任務
- 注冊任務:celery_tasks.main.py
# celery啟動檔案
from celery import Celery
# 創建celery實體
celery_app = Celery('lg')
# 加載celery配置
celery_app.config_from_object('celery_tasks.config')
# 自動注冊celery任務
celery_app.autodiscover_tasks(['celery_tasks.sms'])
2.定義任務:celery_tasks.sms.tasks.py
@celery_app.task(bind=True, name='ccp_send_sms_code', retry_backoff=3)
def ccp_send_sms_code(self, mobile, sms_code):
"""
發送短信異步任務
:param mobile: 手機號
:param sms_code: 短信驗證碼
:return: 成功0 或 失敗-1
"""
try:
send_ret = CCP().send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)
except Exception as e:
logger.error(e)
# 有例外自動重試三次
raise self.retry(exc=e, max_retries=3)
if send_ret != 0:
# 有例外自動重試三次
raise self.retry(exc=Exception('發送短信失敗'), max_retries=3)
return send_ret
step 5 呼叫任務
step 6 啟動celery服務
必須要有celery_tasks的目錄 才可以 執行啟動服務
celery -A celery_tasks.main worker -l info #這是linux的命令
-A指對應的應用程式, 其引數是專案中 Celery實體的位置,
worker指這里要啟動的worker,
-l指日志等級,比如info等級


有時候,需要celery重啟才會有任務反映, 有時候有些報錯,就加幾個引數,可能解決
所以,windows啟動celery 需要加引數,用如下命令啟動服務
celery -A celery_tasks.main worker -l info --pool=solo
or
celery -A celery_tasks.main worker -l info -P eventlet
必須要在manage.py 和 celery_tasks 同一級目錄下運行

呼叫發送短信任務
# 發送短信驗證碼
# CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)
# Celery異步發送短信驗證碼
ccp_send_sms_code.delay(mobile, sms_code)

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/261048.html
標籤:其他
