rest_framework 访问频率(节流)流程
访问频率流程
访问频率流程与认证流程非常相似,只是后续操作稍有不同
当用发出请求时 首先执行dispatch函数,当执行当第二部时:
#2.处理版本信息 处理认证信息 处理权限信息 对用户的访问频率进行限制 self.initial(request, *args, **kwargs)
进入到initial方法:
def initial(self, request, *args, **kwargs): """ Runs anything that needs to occur prior to calling the method handler. """ self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. #2.1处理版本信息 version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted #2.2处理认证信息 self.perform_authentication(request) #2.3处理权限信息 self.check_permissions(request) #2.4对用户的访问频率进行限制 self.check_throttles(request)
#2.4对用户的访问频率进行限制 self.check_throttles(request)
下面 开始 限流的具体分析:
一、执行check_throttles方法
def check_throttles(self, request): """ Check if request should be throttled. Raises an appropriate exception if the request is throttled. """ #遍历throttle对象列表 for throttle in self.get_throttles(): #根据allow_request()的返回值进行下一步操作,返回True的话不执行下面代码,标识不限流,返回False的话执行下面代码,还可以抛出异常 if not throttle.allow_request(request, self): #返回False的话执行 self.throttled(request, throttle.wait())
局部访问频率
throttles.py
#局部访问频率 from rest_framework.throttling import BaseThrottle import time class VisitThorttles(object): visit_thorttles={} def __init__(self): self.history=None def allow_request(self,request,view): current_time=time.time() # 访问用户的IP visit_ip=request.META.get("REMOTE_ADDR") # 第1 次访问时 if visit_ip not in self.visit_thorttles: self.visit_thorttles[visit_ip]=[current_time] return True self.history = self.visit_thorttles[visit_ip] # 第2、3次访问 默认单位时间只能访问3次, if len(self.visit_thorttles[visit_ip])<3: # 最新访问时间放在列表第一个 self.visit_thorttles[visit_ip].insert(0,current_time) return True # # 判断当前时间与用户最早访问时间(列表对三个时间)的差值 if current_time-self.visit_thorttles[visit_ip][-1]>60: self.visit_thorttles[visit_ip].pop() self.visit_thorttles[visit_ip].insert(0,current_time) return True return False
view.py
class BookViewsSet(viewsets.ModelViewSet): # 访问频率 throttle_classes=[VisitThorttles] queryset = Book.objects.all() serializer_class = BookModelSerializer
全局访问频率
throttles.py
#局部访问频率
from rest_framework.throttling import BaseThrottle
import time
class VisitThorttles(object):
visit_thorttles={}
def __init__(self):
self.history=None
def allow_request(self,request,view):
current_time=time.time()
# 访问用户的IP
visit_ip=request.META.get("REMOTE_ADDR")
# 第1 次访问时
if visit_ip not in self.visit_thorttles:
self.visit_thorttles[visit_ip]=[current_time]
return True
self.history = self.visit_thorttles[visit_ip]
# 第2、3次访问 默认单位时间只能访问3次,
if len(self.visit_thorttles[visit_ip])<3:
# 最新访问时间放在列表第一个
self.visit_thorttles[visit_ip].insert(0,current_time)
return True
# # 判断当前时间与用户最早访问时间(列表对三个时间)的差值
if current_time-self.visit_thorttles[visit_ip][-1]>60:
self.visit_thorttles[visit_ip].pop()
self.visit_thorttles[visit_ip].insert(0,current_time)
return True
return False
settings.py
REST_FRAMEWORK={ "DEFAULT_THROTTLE_CLASSES":["api.servise.throttles.VisitThorttles"], }
内置访问频率
htorttles.py
# 内置的htorttles: from rest_framework.throttling import SimpleRateThrottle class VisitThorttles(SimpleRateThrottle): # 范围 visit_rate可自定义,与settings相匹配 scope = "visit_rate" def get_cache_key(self, request, view): return self.get_ident(request)
settings.py
REST_FRAMEWORK = { "DEFAULT_THROTTLE_RATES":{ 'tiga':'10/m', 'anno':'5/m', 'user':'10/m', 'admin':'20/m', } }
待续