一 什麼是throttle
二 Django REST framework是如何實現throttle的
三 Django REST framework中throttle源碼流程django
節流也相似於權限,它用來決定一個請求是否被受權。節流表示着一種臨時的狀態,經常用來控制客戶端對一個
API的請求速率。例如,你能夠經過限流來限制一個用戶在每分鐘對一個API的最多訪問次數爲60次,天天的訪問次數爲1000次。
api
在Django REST framework中主要是經過throttling.py文件裏面的幾個類來實現限流功能的。ide
在整個流程上是在dispatch中的調用的initial方法中的self.check_throttles(request)調用到throttle類中的方法函數
throttle策略的配置:
全局配置settings.pyspa
REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ( # 定義限流類 'rest_framework.throttling.AnonRateThrottle', 'rest_framework.throttling.UserRateThrottle' ), 'DEFAULT_THROTTLE_RATES': { # 定義限流速率,支持秒、分、時、天的限制 'anon': '100/day', 'user': '1000/day' } }
from 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)
FBV3d
@api_view(['GET']) @throttle_classes([UserRateThrottle]) def example_view(request, format=None): content = { 'status': 'request was permitted' } return Response(content)
調用check_throttles方法,在這個方法中會遍歷經過self.get_throttles()獲取到的限流對象列表,默認列表裏面是空的。也就是說默認不會有限流的策略。rest
在視圖函數裏面配置參數,讓其應用上限流策略。咱們這裏以UserRateThrottle這個限流方法爲例。(配置如第二節中的settings.py配置和FBV配置),在這裏繼續第二步的操做,執行UserRateThrottle對象的allow_request方法。
因爲UserRateThrottle這個類自己沒有allow_request方法,因此在其父類SimpleRateThrottle中找這個方法.code
執行allow_request方法,會首先判斷是否認義了self.rate。根據self.rate執行,最終回去查找self.scope屬性,並且這個屬性是必須的。orm
在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方法。這個方法主要用來向客戶端返回還須要多少時間能夠繼續訪問的提示。