Django Rest framework的限流實現流程
目錄
一 什麽是throttle
二 Django REST framework是如何實現throttle的
三 Django REST framework中throttle源碼流程
一 什麽是throttle
節流也類似於權限,它用來決定一個請求是否被授權。節流表示著一種臨時的狀態,常常用來控制客戶端對一個
API的請求速率。例如,你可以通過限流來限制一個用戶在每分鐘對一個API的最多訪問次數為60次,每天的訪問次數為1000次。
二 Django REST framework是如何實現throttle的
在Django REST framework中主要是通過throttling.py文件裏面的幾個類來實現限流功能的。
在整個流程上是在dispatch中的調用的initial方法中的self.check_throttles(request)調用到throttle類中的方法
throttle策略的配置:
全局配置settings.pyREST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( # 定義限流類 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { # 定義限流速率,支持秒、分、時、天的限制 'anon': '100/day', 'user': '1000/day' } }
把限流策略設置在視圖函數上
CBVfrom rest_framework.response import Response from rest_framework.throttling import UserRateThrottle from rest_framework.views import APIView class ExampleView(APIView): throttle_classes = (UserRateThrottle,) def get(self, request, format=None): content = { 'status': 'request was permitted' } return Response(content)
FBV
@api_view(['GET'])
@throttle_classes([UserRateThrottle])
def example_view(request, format=None):
content = {
'status': 'request was permitted'
}
return Response(content)
三 Django REST framework中throttle源碼流程
調用check_throttles方法,在這個方法中會遍歷通過self.get_throttles()獲取到的限流對象列表,默認列表裏面是空的。也就是說默認不會有限流的策略。
在視圖函數裏面配置參數,讓其應用上限流策略。我們這裏以UserRateThrottle這個限流方法為例。(配置如第二節中的settings.py配置和FBV配置),在這裏繼續第二步的操作,執行UserRateThrottle對象的allow_request方法。
由於UserRateThrottle這個類本身沒有allow_request方法,所以在其父類SimpleRateThrottle中找這個方法.執行allow_request方法,會首先判斷是否定義了self.rate。根據self.rate執行,最終回去查找self.scope屬性,而且這個屬性是必須的。
在UserRateThrottle中查找到定義的scope="user", 接著執行self.key語句。這條語句最終調用了UserRateThrottle裏面的get_cache_key方法。
此例中我們沒有配置authenticate,所有會執行get_cache_key裏面的get_indet方法,並最終返回了scope和ident被self.key接收(返回格式:throttle_user_127.0.0.1)。返回self.key之後繼續執行self.history,self.history會返回客戶端的訪問記錄列表,並根據rate的配置去判斷是否是要pop某一條訪問記錄。並最終根據列表長度和允許的長度做對比,判斷客戶端當前是否具有訪問權限。
若最終check_throttles返回True,則繼續執行dispatch。dispatch之後的操作請參考之前寫的django rest framework流程。如果返回False,則會繼續執行self.throttled(request, throttle.wait())。
執行父類SimpleRateThrottle裏面的wait方法。這個方法主要用來向客戶端返回還需要多少時間可以繼續訪問的提示。
Django Rest framework的限流實現流程