REST_FRAMEWORK重要组件--->Throttle
3.节流(throttle)
(1).节流的另外一个说法就是流量控制。假设一个服务器能同时让1000个人在线访问,然而有不法分子企图用流量攻击的手段攻击网站,这就会让路由器和服务器造成瘫痪。在网站收到损害的同时,让其余用户无法更好的与服务器进行交互。节流概念的产生就是让一个ip地址在规定时间内的访问次数得到限制。因为现在更换ip的软件很多,所以在根源上无法控制ip节流的管理。(话不多说,上代码)
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
import time
visit_record={}
class VisitThrottle(BaseThrottle):
def __init__(self):
self.history=None
'''
需求是60s内只能访问三次
'''
def allow_request(self,request,view):
#需要获取用户ip
remote = self.get_ident(request)
ctime=time.time()
if remote not in visit_record:
visit_record[remote]=[ctime,]
return True
history=visit_record.get(remote)
self.history=history
while history and history[-1] < ctime-60:
history.pop()
if len(history) < 3:
history.insert(0,ctime)
return True
def wait(self):
ctime=time.time()
return (60-(ctime - self.history[-1]))
"DEFAULT_THROTTLE_CLASSES":['test3.utils.throttle.VisitThrottle',]
这是一个对于ip地址的节流函数,在这个函数中我们必须完成两个函数的重写、一个是allow_request()、一个是wait().allow_request()返回的是True/False.说的简单一点就是做判断让不让你继续访问,True就是允许访问,False就是不让,但是满足定义条件后又可以继续访问。while history and history[-1] < ctime-60:
history.pop()
wait()函数就是等待放开访问时的显示时间,最开始的是静态的,可以利用最后一个ip进来时间和当前时间做判断来形成一个动态时间的现实。return (60-(ctime - self.history[-1]))
为剩余等待的时间
VisitThrottle类过程流程:
第一次访问时,类得到了访问用户的ip,如果visit_record字典里面没有这个ip,则在里面新建一个这个ip的列表【ip的地址,每次登陆的时间】,返回结果True。如果ip不是第一次登陆的话,则利用history变量获得一个remote列表同时传给self.history,然后做判断,如果列表里面的个数小于三个,继续增加。列表将以【4,3,2,1】的形式增加。同时列表的最后一个值的条件符合了等待时间的条件,则最后一个值删除,结果返回True,说明又可以继续访问了。最新的访问ip值将会放在列表的最左边。
这个类因为是放在内存中运行的,所以当项目重启时,visit_record字典里面的值就会全部清空,从而进行重新记录visit_record数据。
上面的类是继承BaseThrottle,同时也可以继承SimpleThrottle,这个简单。
只要完成对get_cache_key函数的重写,并且定义一个scope名字,而scope的值就是全局配置里面的key,
全局配置中‘3/m’代表着每分钟可以访问三次。
class VisitThrottle(SimpleThrottle):
scope="hyj" #游客模式
def get_cache_key(self,request,view):
return self.get_ident(request)
class VisitThrottle(SimpleThrottle):
scope="userhyj" #用户模式
def get_cache_key(self,request,view):
return request.user.username
"DEFAULT_THROTTLE_RATES":{
'hyj':'3/m',
'userhyj':'3/m',