无码a片

Redis 赶走限流的三种方法

发布日期:2022-06-18 17:09    点击次数:100

Redis 赶走限流的三种方法

 面临越来越多的高并发场景,限流自满的尤为遑急。

虽然,限流有许多种赶走的方法,Redis具有很宏大的功能,我用Redis实行了三种的赶走方法,不错较为简便的赶走其方法。Redis不单是是不错做限流,还不错做数据统计,隔壁的人等功能,这些可能会后续写到。

第一种:基于Redis的setnx的操作

咱们在使用Redis的散布式锁的时候,人人都袒露是依靠了setnx的领导,在CAS(Compare and swap)的操作的时候,同期给指定的key成就了落伍实行(expire),咱们在限流的主要目的等于为了在单元技艺内,有且仅有N数目的恳求大致走访我的代码要领。是以依靠setnx不错很减弱的做到这方面的功能。

比如咱们需要在10秒内铁心20个恳求,那么咱们在setnx的时候不错成就落伍技艺10,当恳求的setnx数目达到20时候即达到了限流遵循。代码比拟简便就不做展示了。

具体的setnx用法不错参照我另一篇博客 RedisTemplate下Redis散布式锁激发的系列问题

虽然这种做法的弱点是好多的,比如当统计1-10秒的时候,无法统计2-11秒之内,如若需要统计N秒内的M个恳求,那么咱们的Redis中需要保持N个key等等问题

第二种:基于Redis的数据结构zset

其实限流触及的最主要的等于滑动窗口, 小12萝8禁在线喷水观看上头也提到1-10怎样变成2-11。其实也等于肇始值和结尾值都各+1即可。

而咱们如若用Redis的list数据结构不错胜券在握的赶走该功能

咱们不错将恳求打酿成一个zset数组,当每一次恳求进来的时候,value保持独一,不错用UUID生成,而score不错用现时技艺戳暗示,因为score咱们不错用来臆测现时技艺戳之内有几许的恳求数目。而zset数据结构也提供了range活动让咱们不错很节略的获得到2个技艺戳内有几许恳求

代码如下

 

public Response limitFlow(){         Long currentTime = new Date().getTime();         System.out.println(currentTime);         if(redisTemplate.hasKey("limit")) {             Integer count = redisTemplate.opsForZSet().rangeByScore("limit", currentTime -  intervalTime, currentTime).size();        // intervalTime是限流的技艺              System.out.println(count);             if (count != null && count > 5) {                 return Response.ok("每分钟最多只可走访5次");             }         }         redisTemplate.opsForZSet().add("limit",UUID.randomUUID().toString(),currentTime);         return Response.ok("走访得胜");     } 

通过上述代码不错做到滑动窗口的遵循,女人与公拘交酡过程高清视频而况能保证每N秒内至多M个恳求,污点等于zset的数据结构会越来越大。赶走方法相对亦然比拟简便的。

第三种:基于Redis的令牌桶算法

提到限流就不得不提到令牌桶算法了。

令牌桶算法说起到输入速度和输出速度,当输出速度大于输入速度,那么等于超出流量礼貌了。

也等于说咱们每走访一次恳求的时候,不错从Redis中获得一个令牌,如若拿到令牌了,那就诠释没超出礼貌,而如若拿不到,则赶走相悖。

依靠上述的思惟,咱们不错鸠合Redis的List数据结构很节略的做到这么的代码,只是简便赶走

依靠List的leftPop来获得令牌

 

// 输出令牌 public Response limitFlow2(Long id){         Object result = redisTemplate.opsForList().leftPop("limit_list");         if(result == null){             return Response.ok("现时令牌桶中无令牌");         }         return Response.ok(articleDescription2);     } 

 

再依靠Java的定时任务,定时往List中rightPush令牌,虽然令牌也需要独一性,是以我这里依然用UUID进行了生成

 

// 10S的速度往令牌桶中添加UUID,只为保证独一性     @Scheduled(fixedDelay = 10_000,initialDelay = 0)     public void setIntervalTimeTask(){         redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());     } 

 

综上,代码赶走肇始都不是很难,针对这些限流方法咱们不错在AOP或者filter中加入以上代码,用来做到接口的限流,最终保护你的网站。

Redis其实还有好多其他的用处,他的作用不单是是缓存,散布式锁的作用。他的数据结构也不单是是只须String,Hash,List,Set,Zset。有趣味趣味的不错后续了解下他的GeoHash算法;BitMap,HLL以及布隆过滤器数据(Redis4.0之后加入,不错用Docker平直装配redislabs/rebloom)结构。



栏目分类



Powered by 无码a片 @2013-2022 RSS地图 HTML地图