如何使用Celery在DRF(Django rest framework)中提高服務器併發實現

一、原理

Celery組成部分
首先圖片中的客戶端代表需要提高併發的服務器,Broker隊列通常保存任務,一般使用Redis/RabbitMQ實現,任務處理者便是Celery實例了
如圖:celery客戶端遇到耗時操作任務的時候,直接將任務發送到Broker(中間人)來協client(任務的發出者)和worker(任務的處理者)。需要注意的是,Celery在DRF中是以單獨的應用出現的,擁有自己的空間,一旦client將任務推送Broker,client就會處理其他請求,完成高度併發並不等待client用戶io操作。

二、實現

首先我們得安裝Celery應用
我們可以使用python的包管理器pip來安裝:

pip install -U Celery

也可從官方直接下載安裝包:Celery官網

tar xvfz celery-0.0.0.tar.gz
cd celery-0.0.0
python setup.py build
python setup.py install

1、搭建Celery應用

我們要在項目的同級目錄搭建新的獨立的Celery應用,首先我們需要創建一個celery_tasks的包,並在celery_tasks/目錄下創建main.py作爲Celery的啓動文件,創建config.py作爲Celery的配置文件。同時把我們需要處理的業務(以msg發送短信爲例)放到celery_tasks/下,併爲其創建tasks.py。注意tasks.py不允許重命名。最終的目錄搭建結構如下圖
Celery基本目錄結構

2、main.py

from celery import Celery

# 爲celery使用django配置文件進行設置,根據自己項目設置
import os
if not os.getenv('DJANGO_SETTINGS_MODULE'):
    os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev'

# 創建celery應用
app = Celery('meiduo')

# 導入celery配置
app.config_from_object('celery_tasks.config')

# 自動註冊celery任務
app.autodiscover_tasks(['celery_tasks.sms'])

3、config.py

# 配置Celery的Broker隊列存放在Redis的14號庫中
broker_url = "redis://127.0.0.1/14"

4、tasks.py

# 加載的日誌模塊
import logging

# 導入Celery實例
from celery_tasks.main import app
# 導入發送短信的實例
from .yuntongxun.sms import CCP

logger = logging.getLogger("django")

# 驗證碼短信模板
SMS_CODE_TEMP_ID = 1

# 注意只有使用Celery實例裝飾的應用纔會生效
@app.task(name='send_sms_code')
def send_sms_code(mobile, code, expires):
    """
    發送短信驗證碼功能實現
    :param mobile: 手機號
    :param code: 驗證碼
    :param expires: 有效期
    :return: None
    """

    try:
        ccp = CCP()
        result = ccp.send_template_sms(mobile, [code, expires], SMS_CODE_TEMP_ID)
    except Exception as e:
        logger.error("發送驗證碼短信[異常][ mobile: %s, message: %s ]" % (mobile, e))
    else:
        if result == 0:
            logger.info("發送驗證碼短信[正常][ mobile: %s ]" % mobile)
        else:
            logger.warning("發送驗證碼短信[失敗][ mobile: %s ]" % mobile)

5、服務端啓動celer_tasks

# 導入Celery具體的應用
from celery_tasks.sms import tasks as sms_tasks

class SMSCodeView(GenericAPIView):
    ...
        # 發送短信驗證碼,一定加delay
        sms_tasks.send_sms_code.delay(mobile, 67868, 5)

        return Response({"message": "OK"})

到此位置就完成了Celery在DRF中的發送短信應用的高併發實現

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章