Django Rest framework頻率原理與限制
前言
開發(fā)平臺(tái)的API接口調(diào)用需要限制其頻率,以節(jié)約服務(wù)器資源和避免惡意的頻繁調(diào)用.
DRF就為我們提供了一些頻率限制的方法.
DRF中的版本、認(rèn)證、權(quán)限、頻率組件的源碼是一個(gè)流程,且頻率組件在最后執(zhí)行.
DRF頻率組件原理
DRF中的頻率控制基本原理是基于訪問次數(shù)和時(shí)間的,當(dāng)然我們也可以通過自己定義的方法來實(shí)現(xiàn).
當(dāng)請(qǐng)求進(jìn)來,走到我們的頻率組件時(shí),DRF內(nèi)部會(huì)有一個(gè)字典來記錄訪問者的IP.
以這個(gè)字典的IP為key,value為一個(gè)列表,存放訪問者每次訪問的時(shí)間:{PI1: [第三次訪問時(shí)間, 第二次訪問時(shí)間, 第一次訪問時(shí)間, ]}
把每次訪問的最新時(shí)間放入列表的最前面,記錄這樣一個(gè)數(shù)據(jù)結(jié)構(gòu)后,通過如下方式限制:
如果我們?cè)O(shè)置的是10秒內(nèi)只能訪問5次:
1.判斷訪問者的IP是否在這個(gè)請(qǐng)求IP的字典里.
2.保證這個(gè)列表里都是都是最近10秒內(nèi)訪問的時(shí)間.
判斷當(dāng)前請(qǐng)求時(shí)間和列表里最早的(也就是最后一個(gè))請(qǐng)求時(shí)間差
如果差大于10秒,說明請(qǐng)求不是最近10秒內(nèi)的,刪除掉最后一個(gè)
繼續(xù)判斷倒數(shù)第二個(gè)、第三個(gè),直到差小于10秒為止
3.判斷列表的長度(即訪問次數(shù))是否大于我們?cè)O(shè)置的5次.
如果大于,則限制其訪問
如果小于,則放行,并把時(shí)間記錄到列表的最前面
使用自帶的頻率限制類
首先 配置頻率限制類
from rest_framework.throttling import SimpleRateThrottle # 導(dǎo)入內(nèi)置的頻率限制類 class DRFThrottle(SimpleRateThrottle): """注意:這里都是必備的屬性、方法和返回值""" scope = 'WD' def get_cache_key(self, request, view): # 拿IP地址 return self.get_ident(request)
然后 配置文件
REST_FRAMEWORK = { # 指定頻率限制的類 "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.DRFThrottle'], # WD是scope定義的值,3/m表示每分鐘不能超過3次訪問 "DEFAULT_THROTTLE_RATES": {"WD": "3/m"}, } """ 如果只是想給單個(gè)視圖做頻率限制: 則刪除這里的"DEFAULT_THROTTLE_CLASSES"配置項(xiàng) 并在要做頻率限制的視圖中指定頻率限制類即可 指定語法:throttle_classes = ["頻率限制類", ] """
開始測試
訪問測試頁面,連續(xù)刷新3次后,可看到:
使用自定義的頻率限制類
首先 自定義頻率限制類
import time VISIT_RECORD = {} # 限制訪問次數(shù)的字典 class MyThrottle(): """ 自定義頻率限制類,一分鐘允許訪問5次 注意:自定義頻率限制類中必須要有allow_request和wait方法 前者用于頻率限制的邏輯,后者用于返回限制時(shí)間還剩多少秒 """ def __init__(self): self.history = [] def allow_request(self, request, view): """用于限制訪問的邏輯""" # 獲取用戶的IP地址 ip = request.META.get('REMOTE_ADDR') if ip not in VISIT_RECORD: VISIT_RECORD[ip] = [time.time(), ] else: history = VISIT_RECORD[ip] self.history = history history.insert(0, time.time()) # 確保訪問時(shí)間在允許范圍之內(nèi) while self.history[0] - self.history[-1] > 60: self.history.pop() # 確定訪問次數(shù)在允許的范圍內(nèi) if len(self.history) >= 5: return False return True def wait(self): """用于返回限制時(shí)間還剩多少秒""" return 60 - (self.history[0] - self.history[-1])
然后 配置文件
REST_FRAMEWORK = { # 指定自定義的頻率限制類 "DEFAULT_THROTTLE_CLASSES": ['blog.throttle.MyThrottle'], } > """ 如果只是想給單個(gè)視圖做頻率限制: 則刪除這里的"DEFAULT_THROTTLE_CLASSES"配置項(xiàng) 并在要做頻率限制的視圖中指定頻率限制類即可 指定語法:throttle_classes = ["頻率限制類", ] """
好了,就到這里吧.
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python 刪除連續(xù)出現(xiàn)的指定字符的實(shí)例
今天小編就為大家分享一篇Python 刪除連續(xù)出現(xiàn)的指定字符的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-06-06Python設(shè)計(jì)模式之工廠方法模式實(shí)例詳解
這篇文章主要介紹了Python設(shè)計(jì)模式之工廠方法模式,結(jié)合實(shí)例形式較為詳細(xì)的分析了工廠方法模式的概念、原理、用法及相關(guān)操作技巧,需要的朋友可以參考下2019-01-01深入解析Python中函數(shù)的參數(shù)與作用域
這篇文章主要介紹了Python中函數(shù)的參數(shù)與作用域,是Python入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-03-03使用Python自制數(shù)據(jù)庫備份工具實(shí)現(xiàn)數(shù)據(jù)定時(shí)覆蓋
這篇文章主要為大家詳細(xì)介紹了如何使用Python自制數(shù)據(jù)庫備份工具實(shí)現(xiàn)數(shù)據(jù)定時(shí)覆蓋功能,文中的示例代碼講解詳細(xì),需要的小伙伴可以參考下2024-03-03Python內(nèi)置函數(shù)int()的具體使用
這篇文章主要為大家介紹了Python內(nèi)置函數(shù)int()的具體使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03python基于tkinter點(diǎn)擊按鈕實(shí)現(xiàn)圖片的切換
這篇文章主要介紹了python基于tkinter點(diǎn)擊按鈕實(shí)現(xiàn)圖片的切換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04Matplotlib實(shí)戰(zhàn)之面積圖繪制詳解
面積圖,或稱區(qū)域圖,是一種隨有序變量的變化,反映數(shù)值變化的統(tǒng)計(jì)圖表,這篇文章主要介紹了如何利用Matplotlib實(shí)現(xiàn)面積圖的繪制,需要的可以參考下2023-08-08