当前位置:网站首页>Redis 实现限流的三种方式
Redis 实现限流的三种方式
2022-07-01 18:41:00 【飘然渡沧海】
Redis 实现限流的三种方式
第一种:基于Redis的setnx的操作
我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就是为了在单位时间内,有且仅有N数量的请求能够访问我的代码程序。所以依靠setnx可以很轻松的做到这方面的功能。
比如我们需要在10秒内限定20个请求,那么我们在setnx的时候可以设置过期时间10,当请求的setnx数量达到20时候即达到了限流效果。代码比较简单就不做展示了。
当然这种做法的弊端是很多的,比如当统计1-10秒的时候,无法统计2-11秒之内,如果需要统计N秒内的M个请求,那么我们的Redis中需要保持N个key等等问题
第二种:基于Redis的数据结构zset
其实限流涉及的最主要的就是滑动窗口,上面也提到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("访问成功");
}
第三种:基于Redis的令牌桶算法
提到限流就不得不提到令牌桶算法了。具体可以参照度娘的解释 [令牌桶算法][Link 1]
令牌桶算法提及到输入速率和输出速率,当输出速率大于输入速率,那么就是超出流量限制了。
也就是说我们每访问一次请求的时候,可以从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());
}
边栏推荐
- 华为云专家详解GaussDB(for MySQL)新特性
- 用GSConv+Slim Neck改进Yolov5,将性能提升到极致!
- Popular science: what does it mean to enter the kernel state?
- Why do independent website sellers start to do social media marketing? The original customer conversion rate can be improved so much!
- AI 训练速度突破摩尔定律;宋舒然团队获得RSS 2022最佳论文奖
- 【快应用】text组件里的文字很多,旁边的div样式会被拉伸如何解决
- 网易游戏,激进出海
- 1. "Create your own NFT collections and publish a Web3 application to show them." what is NFT
- Cache problems after app release
- Yyds dry inventory ravendb start client API (III)
猜你喜欢
Huawei game failed to initialize init with error code 907135000
为什么独立站卖家都开始做社交媒体营销?原来客户转化率能提高这么多!
Leetcode-83 delete duplicate elements in the sorting linked list
Docker deploy mysql8.0
How does factor analysis calculate weights?
C端梦难做,科大讯飞靠什么撑起10亿用户目标?
Leetcode-128 longest continuous sequence
AI 训练速度突破摩尔定律;宋舒然团队获得RSS 2022最佳论文奖
Memo - about C # generating barcode for goods
宏观视角看抖音全生态
随机推荐
Stanford, salesforce|maskvit: masked vision pre training for video prediction
Lefse analysis
Today, with the popularity of micro services, how does service mesh exist?
Memo - about C # generating barcode
Leetcode203 remove linked list elements
ACM mm 2022 video understanding challenge video classification track champion autox team technology sharing
组队学习! 14天鸿蒙设备开发“学练考”实战营限时免费加入!
Docker deploy mysql8.0
AI 训练速度突破摩尔定律;宋舒然团队获得RSS 2022最佳论文奖
数据库基础:select基本查询语句
AI training speed breaks Moore's law; Song shuran's team won the RSS 2022 Best Paper Award
Shell array
R language epidisplay package ordinal or. The display function obtains the summary statistical information of the ordered logistic regression model (the odds ratio and its confidence interval correspo
Popular science: what does it mean to enter the kernel state?
Gameframework eating guide
【直播预约】数据库OBCP认证全面升级公开课
ES6数组去重的三个简单办法
[AGC] how to solve the problem that the local display of event analysis data is inconsistent with that in AGC panel?
Navicat premium 15 permanent cracking and 2021 latest idea cracking (valid for personal testing)
How to realize the applet in its own app to realize continuous live broadcast