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


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

框架中限流功能的實現依賴於封裝好的限流類,設置方式上分為全局設置和局部設置、繼承類設置和自定義類設置。如果要實現限流功能則必須設置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')
  • 自定義限流類代碼:

      # 設置同一個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()), 
  ]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM