如何利用 Redis 实现接口频次限制
介绍:
我们可以利用redis过期Key来实现接口的频次限制。可以自定义一些访问的(速度)限制条件来把那些触发限制的请求拒之门外.一般常用来进行对爬虫的限制.
下面就利用redis来实现了一个简单的案例:
装饰器实现
deffrequency_limit(f): @wraps(f) deffrequency_function(*args,**kwargs): if'csrf_token'insession: token=session.get("csrf_token") url_=request.url_rule redis_key=token+str(url_) conn=redis.StrictRedis(host="127.0.0.1",port="6379",password="123456",db=0) clicks=conn.get(redis_key) ifnotclicks: conn.set(redis_key,1) conn.expire(redis_key,60) else: ifint(clicks)>=5: returnjsonify({'code':500,'status':0,'message':"您的访问频率太快,请稍后再试",'data':[], 'token':token}) overdue=1ifconn.ttl(redis_key)<=0elseconn.ttl(redis_key) conn.set(redis_key,int(clicks)+1) conn.expire(redis_key,overdue) returnf(*args,**kwargs) returnfrequency_function
注:在使用redisKey过期的时候需要注意,在设置了过期时间后,再次改变Key的Value值时,之前设置的过期时间会失效。
解决办法:
1)在修改Value值的时候,查一下过期时间还有多少ttl在修改值的时候把过期时间重新赋值回去(本文用的就是此方法)
2)redis中设置了过期时间,如果list结构中添加一个数据或者改变hset数据的一个字段是不会清除超时时间的;
官方网站看了一下expire的说明:
这样解释的:
Thetimeoutwillonlybeclearedbycommandsthatdeleteoroverwritethecontentsofthekey,includingDEL,SET,GETSETandallthe*STOREcommands.Thismeansthatalltheoperationsthatconceptuallyalterthevaluestoredatthekeywithoutreplacingitwithanewonewillleavethetimeoutuntouched.Forinstance,incrementingthevalueofakeywithINCR,pushinganewvalueintoalistwithLPUSH,oralteringthefieldvalueofahashwithHSETarealloperationsthatwillleavethetimeoutuntouched.
如果用DEL,SET,GETSET会将key对应存储的值替换成新的,命令也会清除掉超时时间;如果list结构中添加一个数据或者改变hset数据的一个字段是不会清除超时时间的;如果想要通过set去覆盖值那就必须重新设置expire。
到此这篇关于如何利用Redis实现接口频次限制的文章就介绍到这了,更多相关Redis实现接口频次限制内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!