为什么使用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({'message': 'OK'})
1,先在环境中安装包celery; pip install celery
2,在项目主目录下创建celery包
3,在celery包下创建_tasks包用于存储celery异步任务
4,在_tasks包下创建config.py文件,用于保存celery的配置信息:url='redis://127.0.0.1:6379/14'
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应用
app=Celery('项目')
#导入celery配置
app.config_from_object('_tasks.config')
#自动注册celery任务
app.autodiscover_tasks(['_tasks.sms'])
在_tasks/sms/包下创建tasks.py文件,用于保存发送短信的异步任务
import logging
from _tasks.main import app
from utill.ytx_sdk.sendSMS import CCP
logging=logging.getlogger('django')
@app.task(name='send_sms_code')
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({"message": "OK"})
启动celery任务
进入到项目目录下,编写命令执行
celery -A _tasks.main worker -l info