异步验证码总结

本文总结了如何将验证码系统改为异步模式,以避免同步操作导致的程序堵塞。通过Celery异步执行任务,利用Redis存储执行结果,从而减轻主程序压力。在实现过程中,详细介绍了可能遇到的问题及解决方案,包括启动Celery服务、数据库配置、错误处理等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问:  为什么要把验证码改为异步的?

  
答:  和异步相对应的是同步   用户输入验证码的时候要先发送验证码;
会有一个等待的过程; 用户要等待验证码的发送,发送之后要输入验证码;
是这样一个流程; 如果有10000个用户一起发送验证码,会导致程序堵塞,
程序就会中断执行;
(这是同步的弊端)
热然异步是 荣联云发送验证码,用户点击用户验证码 ,获取后端接口,
然后celery异步执行, redis存放执行的结果,直接把redis里面把验证码的,
结果取出来,告诉任务就可以了;(任务就是发送验证码)

celery异步执行大大减少了主程序的压力(不会导致主程序堵塞);
把耗时任务放进redis,有任务直接执行;


                                                     可能会遇到的报错


报错一 : object has no attribute 'decode'
  原因:是没有启动异步项目; 或者是数据库里没有执行的结果信息;取出来的为空;
自然也是不能转码成功了;
解决方法:(celery -A 文件名 worker -l info -P eventlet)
celery -A my_celery.test_celery worker -l info -P eventlet


报错二.添加 这两个字段迁移时 先输入1 ; 然后 输入    timezone.now
created_date = models.DateTimeField(default=now(),verbose_name='注册时间')

    last_ogin_data =  models.DateTimeField(verbose_name='最后登录时间')


三:.
在视图中连接数据库一定要 用 localhost不能用(127.0.0.1); 不然后报错连接不上redis;


                                                      记不住的导包和配置  以及知识盲区 :


1.now 是干啥的

# now表示此时时间;
from django.utils.timezone import now

2.加密查询 和 存储密码


from django.contrib.auth.hashers import make_password,check_password

make_password 加密存储密码 如:
new_pwd = make_password(pwd)  这是对前段传递过来的密码进行加密

check_password 既然是 加密存储; 查询也必须要以这种形式查询密码如:
check_password(pwd, user.password):


3.
构造key从redis中查看执行结果 

key = "celery-task-meta-" + resp.id
resp 是调用过来的执行结果
json.loads(json_data)   转化为 dict格式


dict_data['status'] == 'SUCCESS':
SUCCESS 表示执行成功 如果从redis里面取出来的数据 为 SUCCESS 就是执行成功


4.时间戳 表示此时间

TIME_ZONE = 'Asia/ShangHai'  (市区; 表示上海时间)
data= time.strftime('%Y-%m-%d')


5.

我自己的荣联云相关配置
accId = '8aaf0708827c8fd50182aabf61dc0867'
accToken = 'f384ebfd51d04bcea1fd1324e7c91acb'
appId = '8aaf0708827c8fd50182aabf62d4086e'


6. 
# 存储执行信息
broker_url = 'redis://127.0.0.1:6379/15'
# 结果存储设置(储存执行结果)
result_backend = 'redis://127.0.0.1:6379/14'

7.
# 自动发现项目中所有的任务  
 有任务就直接执行(这里的任务指的是发送验证码)(第三部)

app.autodiscover_tasks(settings.INSTALLED_APPS)

8.
配置静态资源   STATICFILES_DIRS = ('static',)


9.
启动异步celery
celery -A my_celery.test_celery worker -l info -P eventlet


10.
                                         ElementUI网址

 https://element.eleme.cn/#/zh-CN/component/form

安装 element

 npm install axios -s element-ui vue-router@3 vuex@3                                                                                      


 Element配置:

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)

思路整理:
1.他要有一个后缀名 min=(后缀名) 
2.在redis里存在执行信息
3.在redis里存放执行结果
4.要投放一个任务;让他来执行
5.要启动任务  (celery -A 文件名 worker -l info -P eventlet)


                             一  :根目录下 建立utils文件夹:并创将
sms_code.py 文件(本文件是用来和 荣联云做一个连接,让他来帮助
                           我们生成验证码)
导包:
import random
import redis
import json
from ronglian_sms_sdk import SmsSDK


1.配置荣联云
accId = '8aaf0708827c8fd50182aabf61dc0867'
accToken = 'f384ebfd51d04bcea1fd1324e7c91acb'
appId = '8aaf0708827c8fd50182aabf62d4086e'


2. def语句定义 一个函数
def send_message(mobile):
3 .sdk = SmsSDK(accId, accToken, appId)
4.定义一个变量  tid = '1'
5.导入随机模块生成随机验证码
6.连接数据库 redis.Redis()(默认是0号数据库) 并构造key进行存储
cls.setex("sms_%s"%mobile,300, data)  最以手机号拼接的这种方式进行存储
7.定义变量 里面传递两个参数  datas = (data, '1')  分别是 data表示生成的验证码
1  表示一分钟后过期


8.调用sdk.sendMessage  里面传递 三个参数  (tid, mobile, datas)
分别是 tib变量 和 datas = (data, '1') 变量  与mobile(手机号参数)

9.   resp_json = json.loads(resp)     return resp_json

将验证码转换为json数据返回

  

对应代码:
import random
import redis
import json
from ronglian_sms_sdk import SmsSDK

accId = '8aaf0708827c8fd50182aabf61dc0867'
accToken = 'f384ebfd51d04bcea1fd1324e7c91acb'
appId = '8aaf0708827c8fd50182aabf62d4086e'

def send_message(mobile):
    sdk = SmsSDK(accId, accToken, appId)
    tid = '1'
    data = random.randint(100000, 999999)
    # 把生成的短信验证码写入redis
    cls = redis.Redis()
    # redis的数据类型: hash list set zset string
    # redis 存放的是:k/v
    cls.setex("sms_%s"%mobile,300, data)

    datas = (data, '5')
    resp = sdk.sendMessage(tid, mobile, datas)
    # print("发送短信验证码响应>>>",resp, type(resp))
    resp_json = json.loads(resp)
    return resp_json

                           二: 创建 my_celery文件夹 ; 并在文件下创建
                         test_celery.py文件(这个文件是用来完成 celery 执行异步的三步)

导包:
import os
from celery import Celery  (导入celery)
from django.conf import settings

1.导入os 模块 ;  并找到根目录下的manage.py 文件 复制
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'admin.settings')
这一行代码;(作用是设置为全局可用)
INSTALLED_APPS(固定格式) 'admin.settings' = 项目名.setting

2.
给所有的任务添加前缀  app = Celery(main="my_tasks")

3.
app.config_from_object(my_celery.config')
加载配置文件 (这个配置文件就是;把加载信息和返回的结果 分别存入redis)

在 'my_celery 下的 config文件 内写入 
                                                (注意不能写为 localhsot)
# 存储执行信息
broker_url = 'redis://127.0.0.1:6379/15'
# 结果存储设置(储存执行结果)
result_backend = 'redis://127.0.0.1:6379/14'

4.


# 自动发现项目中所有的任务
app.autodiscover_tasks(settings.INSTALLED_APPS)

对应代码:
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mall_admin_backend.settings')

# 创建celery对象
# main 是给所有任务添加前缀信息
app = Celery(main="my_tasks")

# 加载配置文件
app.config_from_object('my_celery.config')

# 自动发现项目中所有的任务
app.autodiscover_tasks(settings.INSTALLED_APPS)


                            三:my_celery文件夹下 创建 tasks文件夹下创建 
sms_code_tasks.py文件(用来把发送异步验证码生成任务)

导包:
from my_celery.test_celery import app
from utils.sms_code import send_message

1.

@app.task(task)是一个内置的方法

# 使用@app.task
 来装饰函数, 把函数变成一个任务  (这个任务指的是发送异步验证码)

2.在函数里面 写成一个方法  传入参数手机号;
 调用生成验证码的方法;
把他写进函数里面;表示当做一个任务来执行;
并返回结果
def send_sms_code(mobile):
json_resp = send_message(mobile)
return json_resp


对应代码:

# -*- coding: utf-8 -*-
# @Time    : 2022/8/18 14:11
# @Author  : zyw
# @Email   : panda_kings@163.com
# @File    : my_tasks.py
from my_celery.test_celery import app
from utils.sms_code import send_message

# 使用@app.task 来装饰函数, 把函数变成一个任务
@app.task
def send_sms_code(mobile):
    json_resp = send_message(mobile)
    # print("发送短信验证码的结果是>>>", resp)
    return json_resp


1.接收前段的参数
 mobile = request.query_params.get('mobile')


2.
  resp = send_sms_code.delay(mobile)
调用  执行 验证码 这个方法;

3.

time.sleep(2)


4.
 从redis中获取异步任务执行的结果

构造key 把执行结果从redis里面取出来
cls = redis.Redis(host="localhost",port=6379, db=14)
 key = "celery-task-meta-" + resp.id
redis_data = cls.get(key)

5.
# 把redis中的数据转码
 json_data = redis_data.decode()

6.
 dict_data = json.loads(json_data)
把json格式转化为 dict 就像[{status:SUCCESS},{键:值}]这种形式
原本是 "{\"status\": \"SUCCESS\", \"result\}"  这种格式 


7. 

根据redis里面的执行结果来开判断,执行结果是否成功

来返回响应;

FAILURE 是失败   ;    SUCCESS 是成功

 if dict_data['status'] == 'FAILURE':
            return Response({'message': "短信验证码发送失败", "code": 500})
 if dict_data['status'] == 'SUCCESS':
            return Response({'message': "短信验证码发送成功", "code": 200})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值