欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Django開發(fā)時如何避免頻繁發(fā)送短信驗證碼(python圖文代碼)

 更新時間:2025年08月02日 09:37:52   作者:程序員一諾python  
Django開發(fā)時,為防止頻繁發(fā)送驗證碼,后端需用Redis限制請求頻率,結(jié)合管道技術(shù)提升效率,通過生產(chǎn)者消費者模式解耦業(yè)務(wù)邏輯,引入Celery實現(xiàn)異步任務(wù)處理,優(yōu)化系統(tǒng)性能與可擴展性

避免頻繁發(fā)送 驗證碼

存在的問題:

  • 雖然我們在前端界面做了60秒倒計時功能。
  • 但是惡意用戶可以繞過前端界面向后端頻繁請求 驗證碼。

解決辦法:

  • 在后端也要限制用戶請求 驗證碼的頻率。60秒內(nèi)只允許一次請求 驗證碼。
  • 在Redis數(shù)據(jù)庫中緩存一個數(shù)值,有效期設(shè)置為60秒。

1. 避免頻繁發(fā)送 驗證碼邏輯分析

2. 避免頻繁發(fā)送 驗證碼邏輯實現(xiàn)

1.提取、校驗send_flag

send_flag = redis_conn.get('send_flag_%s' % mobile)
if send_flag:
    return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '發(fā)送 過于頻繁'})

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.界面渲染頻繁發(fā)送 提示信息

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數(shù)據(jù)庫

Redis的 C - S 架構(gòu):

  • 基于客戶端-服務(wù)端模型以及請求/響應(yīng)協(xié)議的TCP服務(wù)。
  • 客戶端向服務(wù)端發(fā)送一個查詢請求,并監(jiān)聽Socket返回。
  • 通常是以阻塞模式,等待服務(wù)端響應(yīng)。
  • 服務(wù)端處理命令,并將結(jié)果返回給客戶端。

存在的問題:

  • 如果Redis服務(wù)端需要同時處理多個請求,加上網(wǎng)絡(luò)延遲,那么服務(wù)端利用率不高,效率降低。

解決的辦法:

  • 管道pipeline

1. pipeline的介紹

管道pipeline

  • 可以一次性發(fā)送多條命令并在執(zhí)行完后一次性將結(jié)果返回。
  • pipeline通過減少客戶端與Redis的通信次數(shù)來實現(xiàn)降低往返延時時間。

實現(xiàn)的原理

  • 實現(xiàn)的原理是隊列。
  • Client可以將三個命令放到一個tcp報文一起發(fā)送。
  • Server則可以將三條命令的處理結(jié)果放到一個tcp報文返回。
  • 隊列是先進先出,這樣就保證數(shù)據(jù)的順序性。

2. pipeline操作Redis數(shù)據(jù)庫

1.實現(xiàn)步驟

1. 創(chuàng)建Redis管道
2. 將Redis請求添加到隊列
3. 執(zhí)行請求

2.代碼實現(xiàn)

  
  
# 創(chuàng)建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)
  
  
# 執(zhí)行請求
  
  
pl.execute()

生產(chǎn)者消費者設(shè)計模式

思考:

  • 下面兩行代碼存在什么問題?

問題:

  • 我們的代碼是自上而下同步執(zhí)行的。
  • 發(fā)送 是耗時的操作。如果 被阻塞住,用戶響應(yīng)將會延遲。
  • 響應(yīng)延遲會造成用戶界面的倒計時延遲。

解決:

  • 異步發(fā)送
  • 發(fā)送 和響應(yīng)分開執(zhí)行,將**發(fā)送從主業(yè)務(wù)中解耦**出來。

思考:

  • 如何將**發(fā)送從主業(yè)務(wù)中解耦**出來。

生產(chǎn)者消費者設(shè)計模式介紹

  • 為了將**發(fā)送從主業(yè)務(wù)中解耦出來,我們引入生產(chǎn)者消費者設(shè)計模式**。
  • 它是最常用的解耦方式之一,尋找**中間人(broker)**搭橋,保證兩個業(yè)務(wù)沒有直接關(guān)聯(lián)。

總結(jié):

  • 生產(chǎn)者生成消息,緩存到消息隊列中,消費者讀取消息隊列中的消息并執(zhí)行。
  • 由美多商城生成發(fā)送 消息,緩存到消息隊列中,消費者讀取消息隊列中的發(fā)送 消息并執(zhí)行。

RabbitMQ介紹和使用

1. RabbitMQ介紹

  • 消息隊列是消息在傳輸?shù)倪^程中保存消息的容器。

  • 現(xiàn)在主流消息隊列有:RabbitMQ、ActiveMQ、Kafka等等。

    • RabbitMQActiveMQ比較

      • 系統(tǒng)吞吐量:RabbitMQ好于ActiveMQ
      • 持久化消息:RabbitMQActiveMQ都支持
      • 高并發(fā)和可靠性:RabbitMQ好于ActiveMQ
    • RabbitMQKafka

      • 系統(tǒng)吞吐量:RabbitMQ弱于Kafka
      • 可靠性和穩(wěn)定性:RabbitMQ好于Kafka比較
      • 設(shè)計初衷:Kafka是處理日志的,是日志系統(tǒng),所以并沒有具備一個成熟MQ應(yīng)該具備的特性。
  • 綜合考慮,本項目選擇RabbitMQ作為消息隊列。

2. 安裝RabbitMQ(ubuntu 16.04)

1.安裝Erlang

  • 由于 RabbitMQ 是采用 Erlang 編寫的,所以需要安裝 Erlang 語言庫。
  
# 1. 在系統(tǒng)中加入 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

  • 安裝成功后,默認就是啟動狀態(tài)。
  
# 1. 先在系統(tǒng)中加入 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
# 關(guān)閉
$ sudo systemctl stop rabbitmq-server

3.Python訪問RabbitMQ

  • RabbitMQ提供默認的administrator賬戶。
  • 用戶名和密碼:guest、guest
  • 協(xié)議:amqp
  • 地址:localhost
  • 端口:5672
  • 查看隊列中的消息:sudo rabbitctl list_queues
  
# Python3虛擬環(huán)境下,安裝pika
$ pip install pika
  
# 生產(chǎn)者代碼:rabbitmq_producer.py
import pika
# 鏈接到RabbitMQ服務(wù)器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))
#創(chuàng)建頻道
channel = connection.channel()
# 聲明消息隊列
channel.queue_declare(queue='zxc')
# routing_key是隊列名 body是要插入的內(nèi)容
channel.basic_publish(exchange='', routing_key='zxc', body='Hello RabbitMQ!')
print("開始向 'zxc' 隊列中發(fā)布消息 'Hello RabbitMQ!'")
# 關(guān)閉鏈接
connection.close()
  
# 消費者代碼:rabbitmq_customer.py 
import pika
# 鏈接到rabbitmq服務(wù)器
credentials = pika.PlainCredentials('guest', 'guest')
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost',5672,'/',credentials))
# 創(chuàng)建頻道,聲明消息隊列
channel = connection.channel()
channel.queue_declare(queue='zxc')
# 定義接受消息的回調(diào)函數(shù)
def callback(ch, method, properties, body):
    print(body)
# 告訴RabbitMQ使用callback來接收信息
channel.basic_consume(callback, queue='zxc', no_ack=True)
# 開始接收信息
channel.start_consuming()

3. 新建administrator用戶

  
# 新建用戶,并設(shè)置密碼
$ sudo rabbitmqctl add_user admin your_password 
# 設(shè)置標簽為administrator
$ sudo rabbitmqctl set_user_tags admin administrator
# 設(shè)置所有權(quán)限
$ sudo rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
# 查看用戶列表
sudo rabbitmqctl list_users
# 刪除用戶
$ sudo rabbitmqctl delete_user admin

4. RabbitMQ配置遠程訪問

1.準備配置文件

  • 安裝好 RabbitMQ 之后,在 /etc/rabbitmq 目錄下面默認沒有配置文件,需要單獨下載。
$ cd /etc/rabbitmq/
$ wget 
$ sudo cp rabbitmq.config.example rabbitmq.config

2.設(shè)置配置文件

$ sudo vim rabbitmq.config
# 設(shè)置配置文件結(jié)束后,重啟RabbitMQ服務(wù)端
$ sudo systemctl restart rabbitmq-server

配置完成后,使用rabbitmq_producer.py、rabbitmq_customer.py測試。

Celery介紹和使用

思考:

  • 消費者取到消息之后,要消費掉(執(zhí)行任務(wù)),需要我們?nèi)崿F(xiàn)。
  • 任務(wù)可能出現(xiàn)高并發(fā)的情況,需要補充多任務(wù)的方式執(zhí)行。
  • 耗時任務(wù)很多種,每種耗時任務(wù)編寫的生產(chǎn)者和消費者代碼有重復(fù)。
  • 取到的消息什么時候執(zhí)行,以什么樣的方式執(zhí)行。

結(jié)論:

  • 實際開發(fā)中,我們可以借助成熟的工具Celery來完成。
  • 有了Celery,我們在使用生產(chǎn)者消費者模式時,只需要關(guān)注任務(wù)本身,極大的簡化了程序員的開發(fā)流程。

1. Celery介紹

  • Celery介紹:

    • 一個簡單、靈活且可靠、處理大量消息的分布式系統(tǒng),可以在一臺或者多臺機器上運行。
    • 單個 Celery 進程每分鐘可處理數(shù)以百萬計的任務(wù)。
    • 通過消息進行通信,使用消息隊列(broker)客戶端消費者之間進行協(xié)調(diào)。
  • 安裝Celery:

$ pip install -U Celery
  • [Celery官方文檔]

2. 創(chuàng)建Celery實例并加載配置

1.定義Celery包

2.創(chuàng)建Celery實例

celery_tasks.main.py

  
# celery啟動文件
from celery import Celery
# 創(chuàng)建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
# 創(chuàng)建celery實例
celery_app = Celery('meiduo')
# 加載celery配置
celery_app.config_from_object('celery_tasks.config')

3. 定義發(fā)送 任務(wù)

1.注冊任務(wù):celery_tasks.main.py

  
# celery啟動文件
from celery import Celery
# 創(chuàng)建celery實例
celery_app = Celery('meiduo')
# 加載celery配置
celery_app.config_from_object('celery_tasks.config')
# 自動注冊celery任務(wù)
celery_app.autodiscover_tasks(['celery_tasks.sms'])

2.定義任務(wù):celery_tasks.sms.tasks.py

  
# bind:保證task對象會作為第一個參數(shù)自動傳入
# name:異步任務(wù)別名
# retry_backoff:異常自動重試的時間間隔 第n次(retry_backoff×2^(n-1))s
# max_retries:異常自動重試次數(shù)的上限
@celery_app.task(bind=True, name='ccp_send_sms_code', retry_backoff=3)
def ccp_send_sms_code(self, mobile, sms_code):
    """
    發(fā)送 異步任務(wù)
    :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('發(fā)送 失敗'), max_retries=3)
    return send_ret

4. 啟動Celery服務(wù)

$ cd ~/projects/meiduo_project/meiduo_mall
$ celery -A celery_tasks.main worker -l info
  • -A指對應(yīng)的應(yīng)用程序, 其參數(shù)是項目中 Celery實例的位置。
  • worker指這里要啟動的worker。
  • -l指日志等級,比如info等級。

5. 調(diào)用發(fā)送 任務(wù)

  
# 發(fā)送 驗證碼
# CCP().send_template_sms(mobile,[sms_code, constants.SMS_CODE_REDIS_EXPIRES // 60], constants.SEND_SMS_TEMPLATE_ID)
# Celery異步發(fā)送 驗證碼
ccp_send_sms_code.delay(mobile, sms_code)

6. 補充celery worker的工作模式

  • 默認是進程池方式,進程數(shù)以當前機器的CPU核數(shù)為參考,每個CPU開四個進程。
  • 如何自己指定進程數(shù):celery worker -A proj --concurrency=4
  • 如何改變進程池方式為協(xié)程方式:celery worker -A proj --concurrency=1000 -P eventlet -c 1000
  
# 安裝eventlet模塊
$ pip install eventlet
# 啟用 Eventlet 池
$ celery -A celery_tasks.main worker -l info -P eventlet -c 1000

總結(jié)

到此這篇關(guān)于Django開發(fā)時如何避免頻繁發(fā)送短信驗證碼(python圖文代碼)的文章就介紹到這了,更多相關(guān)Django避免頻繁發(fā)送短信驗證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python 將列表里的字典元素合并為一個字典實例

    python 將列表里的字典元素合并為一個字典實例

    這篇文章主要介紹了python 將列表里的字典元素合并為一個字典實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • python之如何查找多層嵌套字典的值

    python之如何查找多層嵌套字典的值

    這篇文章主要介紹了python之如何查找多層嵌套字典的值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Python高級特性切片(Slice)操作詳解

    Python高級特性切片(Slice)操作詳解

    在Python中對于具有序列結(jié)構(gòu)的數(shù)據(jù)來說都可以使用切片操作,需注意的是序列對象某個索引位置返回的是一個元素,而切片操作返回是和被切片對象相同類型對象的副本。
    2018-09-09
  • Python實現(xiàn)3行代碼解簡單的一元一次方程

    Python實現(xiàn)3行代碼解簡單的一元一次方程

    這篇文章主要介紹了Python實現(xiàn)3行代碼解簡單的一元一次方程,很適合Python初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下
    2014-08-08
  • Python合并多個Excel數(shù)據(jù)的方法

    Python合并多個Excel數(shù)據(jù)的方法

    這篇文章主要介紹了Python合并多個Excel數(shù)據(jù)的方法也就是說將多個excel中的數(shù)據(jù)合并到另一個表中,本文通過實例代碼相結(jié)合的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友參考下吧
    2018-07-07
  • 三步解決python PermissionError: [WinError 5]拒絕訪問的情況

    三步解決python PermissionError: [WinError 5]拒絕訪問的情況

    這篇文章主要介紹了三步解決python PermissionError: [WinError 5]拒絕訪問的情況,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • Python爬取哆啦A夢-伴我同行2豆瓣影評并生成詞云圖

    Python爬取哆啦A夢-伴我同行2豆瓣影評并生成詞云圖

    哆啦A夢系列是陪伴我,乃至陪伴了幾代人成長的故事.50年來,藤子·F·不二雄先生創(chuàng)造了竹蜻蜓,任意門,時光機器等等無數(shù)的新奇道具,讓大雄和他的小伙伴們經(jīng)歷了各種冒險,也經(jīng)歷了許多充滿戲劇性的啼笑皆非的日常.特意寫了這篇文章,教大家怎么繪制詞云圖,需要的朋友可以參考下
    2021-06-06
  • 使用pytorch提取卷積神經(jīng)網(wǎng)絡(luò)的特征圖可視化

    使用pytorch提取卷積神經(jīng)網(wǎng)絡(luò)的特征圖可視化

    這篇文章主要給大家介紹了關(guān)于使用pytorch提取卷積神經(jīng)網(wǎng)絡(luò)的特征圖可視化的相關(guān)資料,文中給出了詳細的思路以及示例代碼,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-03-03
  • LyScript實現(xiàn)計算片段Hash并寫出Excel的示例代碼

    LyScript實現(xiàn)計算片段Hash并寫出Excel的示例代碼

    本案例將學(xué)習(xí)運用LyScript計算特定程序中特定某些片段的Hash特征值,并通過xlsxwriter這個第三方模塊將計算到的hash值存儲成一個excel表格,感興趣的可以跟隨小編一起學(xué)習(xí)一下
    2022-09-09
  • python對execl 處理操作代碼

    python對execl 處理操作代碼

    這篇文章主要介紹了python對execl 處理操作,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06

最新評論