python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Django避免频繁发送短信验证码

Django开发时如何避免频繁发送短信验证码(python图文代码)

作者:程序员一诺python

Django开发时,为防止频繁发送验证码,后端需用Redis限制请求频率,结合管道技术提升效率,通过生产者消费者模式解耦业务逻辑,引入Celery实现异步任务处理,优化系统性能与可扩展性

避免频繁发送 验证码

存在的问题:

解决办法:

1. 避免频繁发送 验证码逻辑分析

2. 避免频繁发送 验证码逻辑实现

1.提取、校验send_flag

send_flag = redis_conn.get('send_flag_%s' % mobile)
if send_flag:
    return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送 过于频繁'})

2.重新写入send_flag

  
# 保存 验证码
redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
# 重新写入send_flag
redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

3.界面渲染频繁发送 提示信息

if (response.data.code == '4001') {
    this.error_image_code_message = response.data.errmsg;
    this.error_image_code = true;
} else { // 4002
    this.error_sms_code_message = response.data.errmsg;
    this.error_sms_code = true;
}

pipeline操作Redis数据库

Redis的 C - S 架构:

存在的问题:

解决的办法:

1. pipeline的介绍

管道pipeline

实现的原理

2. pipeline操作Redis数据库

1.实现步骤

1. 创建Redis管道
2. 将Redis请求添加到队列
3. 执行请求

2.代码实现

  
  
# 创建Redis管道
  
  
pl = redis_conn.pipeline()
  
  
# 将Redis请求添加到队列
  
  
pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
  
  
# 执行请求
  
  
pl.execute()

生产者消费者设计模式

思考:

问题:

解决:

思考:

生产者消费者设计模式介绍

总结:

RabbitMQ介绍和使用

1. RabbitMQ介绍

2. 安装RabbitMQ(ubuntu 16.04)

1.安装Erlang

  
# 1. 在系统中加入 erlang apt 仓库
$ wget 
$ sudo dpkg -i erlang-solutions_1.0_all.deb
# 2. 修改 Erlang 镜像地址,默认的下载速度特别慢
$ vim /etc/apt/sources.list.d/erlang-solutions.list
# 替换默认值
$ deb  xenial contrib
# 3. 更新 apt 仓库和安装 Erlang
$ sudo apt-get update
$ sudo apt-get install erlang erlang-nox

2.安装RabbitMQ

  
# 1. 先在系统中加入 rabbitmq apt 仓库,再加入 rabbitmq signing key
$ echo 'deb  testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list
$ wget -O-  | sudo apt-key add -
# 2. 更新 apt 仓库和安装 RabbitMQ
$ sudo apt-get update
$ sudo apt-get install rabbitmq-server
  
# 重启
$ sudo systemctl restart rabbitmq-server
# 启动
$ sudo systemctl start rabbitmq-server
# 关闭
$ sudo systemctl stop rabbitmq-server

3.Python访问RabbitMQ

  
# Python3虚拟环境下,安装pika
$ pip install pika
  
# 生产者代码:rabbitmq_producer.py
import pika
# 链接到RabbitMQ服务器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))
#创建频道
channel = connection.channel()
# 声明消息队列
channel.queue_declare(queue='zxc')
# routing_key是队列名 body是要插入的内容
channel.basic_publish(exchange='', routing_key='zxc', body='Hello RabbitMQ!')
print("开始向 'zxc' 队列中发布消息 'Hello RabbitMQ!'")
# 关闭链接
connection.close()
  
# 消费者代码:rabbitmq_customer.py 
import pika
# 链接到rabbitmq服务器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))
# 创建频道,声明消息队列
channel = connection.channel()
channel.queue_declare(queue='zxc')
# 定义接受消息的回调函数
def callback(ch, method, properties, body):
    print(body)
# 告诉RabbitMQ使用callback来接收信息
channel.basic_consume(callback, queue='zxc', no_ack=True)
# 开始接收信息
channel.start_consuming()

3. 新建administrator用户

  
# 新建用户,并设置密码
$ sudo rabbitmqctl add_user admin your_password 
# 设置标签为administrator
$ sudo rabbitmqctl set_user_tags admin administrator
# 设置所有权限
$ sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 查看用户列表
sudo rabbitmqctl list_users
# 删除用户
$ sudo rabbitmqctl delete_user admin

4. RabbitMQ配置远程访问

1.准备配置文件

$ cd /etc/rabbitmq/
$ wget 
$ sudo cp rabbitmq.config.example rabbitmq.config

2.设置配置文件

$ sudo vim rabbitmq.config
# 设置配置文件结束后,重启RabbitMQ服务端
$ sudo systemctl restart rabbitmq-server

配置完成后,使用rabbitmq_producer.pyrabbitmq_customer.py测试。

Celery介绍和使用

思考:

结论:

1. Celery介绍

$ pip install -U Celery

2. 创建Celery实例并加载配置

1.定义Celery包

2.创建Celery实例

celery_tasks.main.py

  
# celery启动文件
from celery import Celery
# 创建celery实例
celery_app = Celery('meiduo')

3.加载Celery配置

celery_tasks.config.py

  
# 指定消息队列的位置
broker_url= 'amqp://guest:guest@192.168.103.158:5672'

celery_tasks.main.py

  
# celery启动文件
from celery import Celery
# 创建celery实例
celery_app = Celery('meiduo')
# 加载celery配置
celery_app.config_from_object('celery_tasks.config')

3. 定义发送 任务

1.注册任务:celery_tasks.main.py

  
# celery启动文件
from celery import Celery
# 创建celery实例
celery_app = Celery('meiduo')
# 加载celery配置
celery_app.config_from_object('celery_tasks.config')
# 自动注册celery任务
celery_app.autodiscover_tasks(['celery_tasks.sms'])

2.定义任务:celery_tasks.sms.tasks.py

  
# bind:保证task对象会作为第一个参数自动传入
# name:异步任务别名
# retry_backoff:异常自动重试的时间间隔 第n次(retry_backoff×2^(n-1))s
# max_retries:异常自动重试次数的上限
@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

4. 启动Celery服务

$ cd ~/projects/meiduo_project/meiduo_mall
$ celery -A celery_tasks.main worker -l info

5. 调用发送 任务

  
# 发送 验证码
# 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)

6. 补充celery worker的工作模式

  
# 安装eventlet模块
$ pip install eventlet
# 启用 Eventlet 池
$ celery -A celery_tasks.main worker -l info -P eventlet -c 1000

总结

到此这篇关于Django开发时如何避免频繁发送短信验证码(python图文代码)的文章就介绍到这了,更多相关Django避免频繁发送短信验证码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文