限流(訪問頻率)組件的使用

限流(訪問頻率)組件的使用

框架中限流功能的實現依賴於封裝好的限流類,設置方式上分爲全局設置和局部設置、繼承類設置和自定義類設置。若是要實現限流功能則必須設置DEAFULRT_THROTTLE_CLASSES和DEAFULRT_THROTTLE_RATES函數

自定義限流類

  • 限流類的基本思路:
  1. 限流須要知道訪問者的本地IP地址,經過地址才能進行記錄訪問次數;
  2. 限流須要瞭解訪問者訪問的時間,經過記錄時間和次數來限制規定時間內訪問者能夠訪問的頻次;
  3. 拿到IP地址後,建立訪問記錄字段,IP做爲key,value是有訪問時的時間組成的列表,最近的訪問時間排在列表的左側,最先的訪問時間排在列表的右側,經過while循環,當最先的時間不符合規定的時間,經過pop()方法把最後一個從列表中剔除。
  4. 經過列表的長度來控制用戶訪問的次數,當知足要求是把用戶訪問的時間插入到列表的下標爲0的位置。
  5. wait方法主要功能是返回距離下次能夠正常訪問的時間,注意返回值必須是數值,不能是字符串,基本思路是:須要用當前時間減去被剔除的訪問時間獲得的是剛過去多少時間,用限制的總時間再減去這個時間便可獲得剩餘限制時間。測試

    Note
    須要注意兩點:
    1. 自定義的限流類中必須包含allow_request和wait方法,這兩個方法名不能寫錯,不然系統沒法運行。
    2. 獲取IP地址的方法有兩種:
    • 方式一: remote_addr = request._request.META.get('REMOTE_ADDR')
    • 方式二: remote_addr = request.META.get('REMOTE_ADDR')
  • 自定義限流類代碼:url

    # 設置同一個IP一分鐘內只能訪問三次的限流功能
      import time
      VISIT_RECORD = {}
      class VisitThrottle(object):
          def __init__(self):
              self.history = None
              self.ctime = None
              self.time = None
              # 變量默認爲空
          def allow_request(self, request, view):
              remote_addr = request._request.META.get('REMOTE_ADDR')
              # 獲取用戶IP
              # 若是繼承基類,那麼這個remote_addr = self.get_indent(request),直接調用繼承類中的方法
              ctime = time.time()
              self.ctime = ctime
              # 獲取當前時間
              if not remote_addr in VISIT_RECORD:
                  VISIT_RECORD[remote_addr] = [ctime,]
                  # 不存在記錄,建立記錄
              history = VISIT_RECORD.get(remote_addr)
              self.history = history
              while history and history[-1] < ctime - 60:
                  history.pop()
                  # 距離當前時間超過一分鐘的回自動剔除
              if len(history) <= 3:
                  history.insert(0, ctime)
                  return True
                  #返回True表示能夠繼續訪問
    
          def wait(self):
              self.time = 60 - (self.ctime - self.history[-1])
              return self.time
              # 直接返回時間

全局設置的實現

--settings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES':[
        'rest_framework.throttling.AnonRateThrottle',
        # 匿名用戶的限流
        'rest_framework.throttling.UserRateThrottle'
        # 註冊用戶的限流
    }    
    'DEFAULT_THROTTLE_RATES': {
        'anon': '2/minute',
        # 匿名用戶每分鐘限制訪問次數爲5次
        'user': '5/minute',
        # 註冊用戶每分鐘限制訪問次數爲15次
    }
--views.py
# 全侷限流功能的實現
class Demo5APIView(APIView):
    # 全局設置不須要在視圖類中進行操做
    def get(self, request):
        # 投票頁面
        return Response('這是投票頁面')
--urls.py
    urlpatterns = [
        path('demo7/',views.Demo7APIView.as_view()),
        ]

局部設置的實現

--settings.py
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'anon': '2/minute',
        # 匿名用戶每分鐘限制訪問次數爲5次
        'user': '5/minute',
        # 註冊用戶每分鐘限制訪問次數爲15次
    }
}
--views.py
# 局部限流功能的實現
class Demo6APIView(APIView):
    throttle_classes = [UserRateThrottle, AnonRateThrottle]
    # 局部設置須要寫在視圖函數中,以列表的形式來設置
    def get(self, reqeust):
        return Response('測試局部限流功能')
--urls.py
urlpatterns =[
     path('demo6/', views.Demo6APIView.as_view()),
   ]

自定義限流功能的實現

--settings.py
'DEFAULT_THROTTLE_CLASSES': [
    'rest_framework.throttling.ScopedRateThrottle',
    # 自定義限流須要用到的類
    ],

'DEFAULT_THROTTLE_RATES': {
    'contacts': '5/hour',
    # 自定義限流的速率設置
    }
}

自定義限流功能的實現

--views.py
from rest_framework.throttling import ScopedRateThrottle
class Demo7APIView(APIView):
   throttle_scope = 'contacts'
   # 經過throttle_scope來設置限流速率名稱
   def get(self, request):
       return Response("測試自定義限流功能")
-- urls.py
urlpatterns = [
   path('demo7/', views.Demo7APIView.as_view()), 
  ]
相關文章
相關標籤/搜索