為什麼使用celery進行非同步操作簡訊傳送?
使用者在進行註冊時,如果在不使用非同步的情況下,使用者輸入個人手機號之後,主程式就會在按照之前的流程執行,但是第三方的手機號碼傳送過程中會產生諸多的問題(例如:網路延遲,第三方的伺服器請求問題等等),等待,阻塞,都會造成使用者體驗效果的下降,造成一定的影響,而使用celery非同步實現傳送簡訊驗證碼,在主程序進行的同時,傳送簡訊的請求也進行處理,以此來解決上述,網路延遲等問題,提高使用者使用體驗,同時提高伺服器的使用效率。
如何使用celery實現非同步操作完成任務?
提前建立工具檔案包 將第三方傳送簡訊的sdk**放入,按照第三方使用文件使用
建立常量檔案constans.py,用於定義常量
#簡訊驗證碼過期時間
sms_code_expires=200 以秒為單位
#傳送資訊簡訊的間隔
sms_flag_expires=60
在views.py中定義實現檢視
from rest_framework.views import apiview
from rest_framework.response import response
from django_redis import get_redis_connection
from utils.ytx_sdk.sendsms import ccp
from rest_framework import exceptions
import random
from . import contants
class smscodeview(apiview):
def get(self, request, mobile):
、傳送簡訊驗證碼
:param request: 請求物件,不需要傳遞
:param mobile: 手機號,需要傳遞
:return: 是否傳送成功
# 資料儲存在redis中,所以獲取redis連線
redis_cli = get_redis_connection('verify_codes')
# 判斷此手機號60秒內是否發過簡訊,如果已經傳送則不傳送
sms_flag = redis_cli.get('sms_flag_' + mobile)
if sms_flag:
raise exceptions.validationerror('傳送驗證碼太頻繁')
# 隨機生成6位簡訊驗證碼
sms_code = random.randint(100000, 999999)
#使用管道方式互動redis
redis_pipeline=redis_cli.pipeline()
# 儲存驗證碼
redis_pipeline.setex('sms_code_' + mobile, contants.sms_code_expires, sms_code)
# 儲存60秒傳送標記
redis_pipeline.setex('sms_flag_' + mobile, contants.sms_flag_expires, 1)
#執行redis_pipeline.execute()
# 傳送簡訊
# sms_code_expires = contants.sms_code_expires / 60
# ccp.sendtemplatesms(mobile,sms_code,sms_code_expires,1)
print(sms_code)
# 響應
return response()
1,先在環境中安裝包celery; pip install celery
2,在專案主目錄下建立celery包
3,在celery包下建立_tasks包用於儲存celery非同步任務
4,在_tasks包下建立config.py檔案,用於儲存celery的配置資訊:url='redis:'
5,在_tasks包下建立main.py檔案,作為celery的啟動檔案
配置如下:
from celery import celery
#為celery使用django配置檔案進行設定
import os
if not os.getenv('django_setting_module'):
os.environ[' django_setting_module']='專案名.settings'
#建立celery應用
#匯入celery配置
#自動註冊celery任務
在_tasks/sms/包下建立tasks.py檔案,用於儲存傳送簡訊的非同步任務
import logging
from utill.ytx_sdk.sendsms import ccp
logging=logging.getlogger('django')
def send_sms_code(mobile,code,expires,template_id)
"""傳送簡訊驗證碼
mobile:手機號
code:驗證碼
expires:有效期
"""try:
# result = ccp.send_template_sms(mobile, [code, expires], template_id)
result = 0
print(code)
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)
在views.py寫入smscodeview檢視,使用celery非同步傳送簡訊
from celery_tasks.sms.tasks import send_sms_code
class smscodeview(genericapiview):
...# 傳送簡訊驗證碼
sms_code_expires = str(constants.sms_code_redis_expires // 60)
send_sms_code.delay(mobile,sms_code,sms_code_expires,1)
return response()
啟動celery任務
進入到專案目錄下,編寫命令執行
celery -a _tasks.main worker -l info
celery非同步任務傳送簡訊驗證碼
進行處理,處理之後把結果儲存到backend中。在mian.py中主要是celery的主程式 from celery import celery import os if not os.getenv django settings module os.environ django settings ...
celery非同步任務 傳送簡訊驗證碼
引入 我們在進行註冊賬號業務中,由 django 生成傳送簡訊訊息,我們前面是交給第三方服務雲通訊來傳送簡訊驗證碼的,這一過程依賴網路。如果乙個使用者在註冊的時候網路很差,則會導致傳送簡訊的過程一直堵塞,導致前端介面一直得不到資料返回。這不是我們希望看到的。如下圖 解決方案 我們把傳送簡訊這一任務交...
celery非同步傳送簡訊
celery專案中的所有導包位址,都是以celery base dir為基準設定 執行celery命令時,也需要進入celery base dir目錄執行 celery base dir os.path.dirname os.path.abspath file def send sms code s...