我的编程空间,编程开发者的网络收藏夹
学习永远不晚

redis实现限流的三种方法

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

redis实现限流的三种方法

今天小编给大家分享的是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("访问成功");
 }

通过上述代码可以做到滑动窗口的效果,并且能保证每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)结构。

关于redis实现限流的三种方法就分享到这里了,希望以上内容可以对大家有一定的参考价值,可以学以致用。如果喜欢本篇文章,不妨把它分享出去让更多的人看到。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

redis实现限流的三种方法

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java实现5种限流算法及7种限流方式

本文主要介绍了Java实现5种限流算法及7种限流方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2022-11-13

Redis限流的实现方法有哪些

本篇内容主要讲解“Redis限流的实现方法有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Redis限流的实现方法有哪些”吧!一、简单的限流基本原理当系统处理能力有限,如何组织计划外的请求对
2023-06-22

Redis实现IP限流的2种方式举例详解

目录通过reids实现通过Lua+Redis实现注意事项总结 通过reids实现限流的流程图在配置文件配置限流参数blackIP:# ip 连续请求的次数continue-counts: ${counts:3}# ip 判断的时间间隔
Redis实现IP限流的2种方式举例详解
2024-08-13

Java限流实现的几种方法详解

这篇文章主要介绍了Java限流实现的几种方法,通俗的说,限流就是限制一段时间内,用户访问资源的次数,减轻服务器压力,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2022-12-03

Springboot使用redis实现接口Api限流的方法

这篇文章主要介绍“Springboot使用redis实现接口Api限流的方法”,在日常操作中,相信很多人在Springboot使用redis实现接口Api限流的方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-20

redis实现限流的方式有哪些

Redis实现限流的方式有以下几种:1. 固定窗口算法:对请求进行计数,在固定的时间窗口内,如果请求数超过阈值,则拒绝请求。2. 滑动窗口算法:将时间窗口划分为固定的时间段,在每个时间段内,记录请求数量,并计算总请求数。如果总请求数超过阈值
2023-09-14

redis lua限流算法如何实现

本篇内容介绍了“redis lua限流算法如何实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!限流算法常见的限流算法计数器算法漏桶算法令牌
2023-07-02

redis lua限流算法实现示例

目录限流算法计数器算法场景分析算法实现漏铜算法令牌桶算法:算法实现限流算法常见的限流算法计数器算法漏桶算法令牌桶算法计数器算法  顾名思义,计数器算法是指在一定的时间窗口内允许的固定数量的请求.比如,2s内允许1
2022-07-15

编程热搜

目录