【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)

2024-04-04 18:20

本文主要是介绍【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  📝个人主页:哈__

期待您的关注 

本文介绍SpringBoot整合Redis并且进行接口的限流,文章主要介绍的是一种思想,具体代码还要结合实际。

一、Windows安装Redis

Redis的解压包我放在了百度网盘上,有需要的可以下载。

Redis-x64-3.0.504 解压码:uhwj

二、启动Redis

我们在本地解压下载的Redis压缩包,打开解压后的目录,首先启动redis-server.exe,之后在启动redis-cli.exe。

启动成功截图如下。

三、SpringBoot整合Redis 

1.引入依赖 

         <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

2.添加配置文件application.yml

 我们并没有设置密码所以不用配置。

spring: redis:host: 127.0.0.1port: 6379

3.创建RedisController

我们现在是介绍思想,所以传入了一个用户的id来判断是哪一个用户访问的接口。我们对redis中保存的key为用户id的键值对进行一个自增操作,然后返回这个自增后的值,这个值代表的就是我们在十秒钟内访问接口的次数。每次访问我们都重新设置这个键值对的有效时间,如果值大于5说明我们访问的次数已经达到了系统对个人十秒钟内访问次数的限制了,就不可以执行我们的业务逻辑。

@Resource
private RedisTemplate<String, String> redisTemplate;@GetMapping("/test2")public String test2(String id){Long increment = redisTemplate.opsForValue().increment(id);redisTemplate.expire(id,10,TimeUnit.SECONDS);if(increment > 5){return "不可以访问,访问次数为"+increment;}return "可以访问,访问次数为"+increment;}

之后启动我们的SpringBoot项目。我这里使用的是PostMan进行的接口测试。

进行第一次访问。

第二次。

 

第五次 。

第六次。第六次可以看到接口的返回值为不可以访问,说明我们的访问次数已经上限了,这时候就要等十秒后再次访问了。

 

四、Redis限流的几种方法 

1.基于Redis的数据结构zset(滑动窗口)

思想比较容易接收,我们定一个这样一个key为limit的列表,每当我们发送一次请求的时候,我们向这个列表当中添加当前的时间戳(前提是没有被限流),当然,在我们进行数据的添加之前需要进行是否需要进行限流。我们设定intervalTime为限流的时间间隔,我们从limit列表中获取我们访问接口的时间currentTIme-intervalTime,这样我们判断一下(currentTIme-intervalTime,currentTime)范围内的时间戳个数,也就是我们请求的次数,这样就能判断是否超过限制了。这里我用一张图来表示。

既然叫做滑动窗口,那这个窗口的大小就是我们进行限流的时间间隔,这个窗口在我们的时间轴上进行移动。

代码如下:

@GetMapping("/test3")public String test3(){int intervalTime = 10;Long currentTime = new Date().getTime();if(Boolean.TRUE.equals(redisTemplate.hasKey("limit"))) {Integer count = Objects.requireNonNull(redisTemplate.opsForZSet().rangeByScore("limit", currentTime - intervalTime, currentTime)).size();if (count != null && count > 5) {return "每分钟最多只能访问5次";}}redisTemplate.opsForZSet().add("limit", UUID.randomUUID().toString(),currentTime);return "访问成功";}

 2.基于Redis的令牌桶算法

这个就好理解了,一个筐子里十个苹果大家都去拿,拿到了就可以吃,拿不到就等着别人放。在Redis里我们在一个列表里放令牌,用户访问接口去尝试拿这个令牌,拿到了就能访问接口,拿不到就进行限流,当然除了拿令牌之外还放令牌,我们通过定时任务向列表内放令牌。

 @GetMapping("/test3")public String test3(){Object result = redisTemplate.opsForList().leftPop("limit_list");if(result == null){return "当前令牌桶中无令牌,无法访问";}return "访问成功";}@Scheduled(fixedDelay = 100,initialDelay = 0)public void setLimitListTask(){redisTemplate.opsForList().rightPush("limit_list",UUID.randomUUID().toString());}

定时任务到底如何使用,大家可以自行搜索一下。还有一些其他的方式本文就不在介绍了。

这篇关于【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/876512

相关文章

使用Vue-ECharts实现数据可视化图表功能

《使用Vue-ECharts实现数据可视化图表功能》在前端开发中,经常会遇到需要展示数据可视化的需求,比如柱状图、折线图、饼图等,这类需求不仅要求我们准确地将数据呈现出来,还需要兼顾美观与交互体验,所... 目录前言为什么选择 vue-ECharts?1. 基于 ECharts,功能强大2. 更符合 Vue

如何合理使用Spring的事务方式

《如何合理使用Spring的事务方式》:本文主要介绍如何合理使用Spring的事务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、底层构造1.1.事务管理器1.2.事务定义信息1.3.事务状态1.4.联系1.2、特点1.3、原理2. Sprin

springboot+vue项目怎么解决跨域问题详解

《springboot+vue项目怎么解决跨域问题详解》:本文主要介绍springboot+vue项目怎么解决跨域问题的相关资料,包括前端代理、后端全局配置CORS、注解配置和Nginx反向代理,... 目录1. 前端代理(开发环境推荐)2. 后端全局配置 CORS(生产环境推荐)3. 后端注解配置(按接口

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

uniapp小程序中实现无缝衔接滚动效果代码示例

《uniapp小程序中实现无缝衔接滚动效果代码示例》:本文主要介绍uniapp小程序中实现无缝衔接滚动效果的相关资料,该方法可以实现滚动内容中字的不同的颜色更改,并且可以根据需要进行艺术化更改和自... 组件滚动通知只能实现简单的滚动效果,不能实现滚动内容中的字进行不同颜色的更改,下面实现一个无缝衔接的滚动

C#通过进程调用外部应用的实现示例

《C#通过进程调用外部应用的实现示例》本文主要介绍了C#通过进程调用外部应用的实现示例,以WINFORM应用程序为例,在C#应用程序中调用PYTHON程序,具有一定的参考价值,感兴趣的可以了解一下... 目录窗口程序类进程信息类 系统设置类 以WINFORM应用程序为例,在C#应用程序中调用python程序

Java如何根据word模板导出数据

《Java如何根据word模板导出数据》这篇文章主要为大家详细介绍了Java如何实现根据word模板导出数据,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... pom.XML文件导入依赖 <dependency> <groupId>cn.afterturn</groupId>

利用Python实现可回滚方案的示例代码

《利用Python实现可回滚方案的示例代码》很多项目翻车不是因为不会做,而是走错了方向却没法回头,技术选型失败的风险我们都清楚,但真正能提前规划“回滚方案”的人不多,本文从实际项目出发,教你如何用Py... 目录描述题解答案(核心思路)题解代码分析第一步:抽象缓存接口第二步:实现两个版本第三步:根据 Fea

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

Go语言使用slices包轻松实现排序功能

《Go语言使用slices包轻松实现排序功能》在Go语言开发中,对数据进行排序是常见的需求,Go1.18版本引入的slices包提供了简洁高效的排序解决方案,支持内置类型和用户自定义类型的排序操作,本... 目录一、内置类型排序:字符串与整数的应用1. 字符串切片排序2. 整数切片排序二、检查切片排序状态: