Redis基于Redisson的限流和限流算法

限流

限流是在高并发或者某个瞬间高并发时,为了保证系统的稳定性,对超出服务处理能力之外的请求进行拦截,对访问服务的流量进行限制。

常见的限流算法有四种:固定窗口限流算法、滑动窗口限流算法、漏桶限流算法和令牌桶限流算法。

固定窗口限流算法

将每个固定时间设置为每个固定窗口,每个固定窗口只能处理固定数量的请求,如果这个窗口处理了限定的请求数量,之后的请求都不再处理,直到下一个时间窗口。固定窗口限流实现简单,但是会出现流量突刺的问题,假设窗口为1s,请求数量为100,999ms 之前都没有请求来,999ms 的时候来了100个请求都接收了,此时下一个窗口的第1ms 的时候也来了100个请求,这就导致系统在短短2ms 内要处理200个请求,无疑会加重系统负载。

打个比方,有一个面馆,每个小时只能20人吃面,划分9点到10点为一个窗口,10点到11点为一个窗口,假设9点59分59秒来了20人吃面,10点00分01秒来了20人吃面,这就导致两秒钟面馆要做40碗面,压力剧增。

 

滑动窗口限流算法

固定窗口是将时间划分为多个窗口,比如每一小时都是一个固定窗口,9点到10点是一个窗口,10点到11点是一个窗口,每个窗口随着时间变化逐渐变小,所以会出现两个流量突刺的问题。

滑动窗口是将一个小时作为窗口,窗口的大小始终不变,在这个窗口内只能存在20个请求。

打个比方,还是那个面馆,这个面馆是一个滑动窗口,面馆里有20个位置,最大只能容纳20个人同时吃面。假如出现上面的情况,9点59分59秒来了20人,10点00分01秒来了20人,虽然来了40人,但是店里只能容纳20人吃面。后来的20人只能等着或者被拒绝。

漏桶限流算法 

系统处理请求就像是一个往一个漏桶中装水,如果装的水量很大,下面的孔来不及流出去,水就会溢出来。保证系统始终以稳定的速率处理请求,不会出现压力激增的问题。

但是因为始终以恒定的速率处理请求,如果系统有多余的资源,效率比较慢。

令牌桶算法

在漏桶的基础上,加上了令牌的概念,以恒定的速率往桶里加令牌,请求到来的时候先获取令牌,然后被处理,如果处理请求的速率慢于加令牌的速度,桶内始终会有令牌,那么请求来了就能被处理。如果处理速率快于令牌,那么桶里会出现没有令牌的情况,到来的请求就会被拒绝。

打个比方,流水线始终以固定的速率生产配件,配件即为令牌,生产的配件会被放在仓库,仓库就是桶,工厂接到了订单请求会先确认仓库中,如果有配件,就会处理订单,如果没配件了,订单就会被拒绝。

Redisson 实现限流 

github地址:

redisson/redisson: Redisson - Easy Redis Java client and Real-Time Data Platform. Sync/Async/RxJava/Reactive API. Over 50 Redis based Java objects and services: Set, Multimap, SortedSet, Map, List, Queue, Deque, Semaphore, Lock, AtomicLong, Map Reduce, Bloom filter, Spring Cache, Tomcat, Scheduler, JCache API, Hibernate, RPC, local cache ... (github.com)

实现主要参考开源地址

 1. 配置依赖

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.30.0</version>
</dependency>  

2. 创建Redisson配置类

/*** Redisson 配置*/
@Configuration
@EnableCaching
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {private String port;private String host;private Integer database;private Integer timeout;@Bean(destroyMethod = "shutdown")public RedissonClient redissonClient(){// 1. 创建配置Config config = new Config();String redisAddress = String.format("redis://%s:%S",host,port);//设置redis地址,redis 库,过期时间config.useSingleServer().setAddress(redisAddress).setDatabase(database).setTimeout(timeout);// 2. 创建Redisson实例// Sync and Async APIreturn Redisson.create(config);}
}

3. 创建限流管理器

@Service
public class RedisLimiterManager {@Resourceprivate RedissonClient redissonClient;/*** 限流,令牌桶算法* @param key 区分不同的限流器,这里是对应的redis的key*/public void doRateLimit(String key){RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);//每秒执行两个请求,设置速率rateLimiter.trySetRate(RateType.OVERALL,2,1, RateIntervalUnit.SECONDS);//每个请求到来请求 1 个令牌boolean b = rateLimiter.tryAcquire(1);if(!b){throw new BusinessException(ErrorCode.SYSTEM_ERROR,"请求频繁,请稍后再试");}}
}

4. 调用限流管理器即可

//注入管理器
@Resourceprivate RedisLimiterManager redisLimiterManager;//调用
//限流每个用户调用方法的次数redisLimiterManager.doRateLimit("genCharByAi:"+userId);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/707114.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 自动生成数据库设计文档

背景&#xff1a;有时候急需要数据库设计文档&#xff0c;手写太麻烦&#xff0c;这里介绍一款开源组件&#xff0c;可以自动根据数据库连接生成数据库设计文档 废话不多说&#xff0c;直接上代码 导入maven包 <dependency><groupId>org.freemarker</groupId>…

openGauss一主两备集群异常断电后不能正常启动的解决过程简记

背景 因异常断电后opengauss 5.0.0版本&#xff0c;一主两备集群启动失败。 报错不是主机&#xff0c;由于当时没有截图&#xff0c;查看日志后发现报错是&#xff1a; 定位过程 Day1 1. 尝试用另外两台机器启动每台机器 发现都报错自己不是主机&#xff0c;像极了唐僧被妖…

计算机网络-路由策略与路由控制一

到目前为止我们学习了路由与交换基础&#xff0c;路由协议有静态、RIP、OSPF、IS-IS等&#xff0c;但是根据实际组网需求&#xff0c;往往需要实施一些路由策略对路由信息进行过滤、属性设置等操作&#xff0c;通过对路由的控制&#xff0c;可以影响数据流量转发。 因此我们开始…

webpack优化构建速度示例-IgnorePlugin:

IgnorePlugin是webpack的一个内置插件&#xff0c;允许你忽略某些特定的模块或文件 webpack.config.jsconst config {entry: ./src/index.js,output: {filename: main.js},mode: development, }module.exports config;src/index.js import moment from moment console.log(mo…

高中数学:平面向量-数乘运算

一、定义 顾名思义 向量的数乘运算&#xff0c;就是数量与向量相乘的运算 λ a → \mathop{a}\limits ^{\rightarrow} a→&#xff0c;λ∈R 二、λ a → \mathop{a}\limits ^{\rightarrow} a→的性质 1、长度 |λ|*| a → \mathop{a}\limits ^{\rightarrow} a→| |λ a …

如何管理研发人员

在日益激烈的市场竞争中&#xff0c;企业的核心竞争力往往取决于其技术创新能力和研发实力。然而&#xff0c;随着企业研发的深入和技术的积累&#xff0c;研发人员泄密的风险也愈发严重。如何防止研发人员泄密&#xff0c;已经成为企业面临的重要问题。本文将从加强员工保密意…

你好 GPT-4o!

你好 GPT-4o&#xff01; OpenAI公司宣布推出 GPT-4o&#xff0c;这是OpenAI的新旗舰模型&#xff0c;可以实时对音频、视觉和文本进行推理。 GPT-4o&#xff08;“o”代表“o​​mni”&#xff09;是迈向更自然的人机交互的一步——它接受文本、音频、图像和视频的任意组合作…

2020 年第一届辽宁省大学生程序设计竞赛

比赛经历&#xff1a;摸鱼划水了一个多小时又是只会签到&#xff0c;看来还得提升自己的解题能力写了六题 补题&#xff1a;E线段树维和区间平方和&#xff0c;比较经典好久没写过线段树了傻了&#xff0c;注意维护lazy J计算几何&#xff0c;看来得提上日程了&#xff0c;用叉…

Ipython 解释器之魔法命令

文章目录 1. 性能分析 %timeit 和 %prun2. 交互式绘图 %matplotlib inline3. 查看和修改环境变量 %env4. 读取并执行外部脚本 %run5. 调试 %debug6. 代码 profiling with %lprun7. 记忆函数结果 %memit 和 %mprun8. 交互式Shell与系统命令 %shell9. 自动补全与文档查看 %autoin…

【面试干货】一个数组的倒序

【面试干货】一个数组的倒序 1、实现思想2、代码实现 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1、实现思想 创建一个新的数组&#xff0c;然后将原数组的元素按相反的顺序复制到新数组中。 2、代码实现 package csdn;public class…

CentOS7使用Docker安装Redis图文教程

1.拉取Redis镜像 这里制定了版本&#xff0c;不指定默认latest最新版 docker pull redis:6.0.8提示信息如下即为下载成功 2.上传配置文件 官方配置文件&#xff08;找自己对应的版本&#xff09;&#xff1a;reids.conf 或者将如下配置文件命名为redis.conf&#xff0c;上…