Guava-RateLimiter详解
简介: 常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取令牌,只有取到令牌的请求才会被成功响应,获取的方式有两种:阻塞等待令牌或者取不到立即返回失败,下图来自网上: ratelimite原理图 本次实战,我们用的是guava的RateLimiter,场景是spring mvc在处理请求时候,从桶中申请令牌,申请到了就成功响应,申请不到时直接返回失败。
常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取令牌,只有取到令牌的请求才会被成功响应,获取的方式有两种:阻塞等待令牌或者取不到立即返回失败,下图来自网上:

ratelimite原理图
本次实战,我们用的是guava的RateLimiter,场景是spring mvc在处理请求时候,从桶中申请令牌,申请到了就成功响应,申请不到时直接返回失败。
实例
1、添加guava jar包
<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>18.0</version></dependency>
2、AccessLimitService.java 限流服务封装到一个类中AccessLimitService,提供tryAcquire()方法,用来尝试获取令牌,返回true表示获取到
@Service
public class AccessLimitService {//每秒只发出5个令牌RateLimiter rateLimiter = RateLimiter.create(5.0);/*** 尝试获取令牌* @return*/public boolean tryAcquire(){return rateLimiter.tryAcquire();}
}
3、Controller层每次收到请求的时候都尝试去获取令牌,获取成功和失败打印不同的信息
@Controller
public class HelloController {private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");@Autowiredprivate AccessLimitService accessLimitService;@RequestMapping("/access")@ResponseBodypublic String access(){//尝试获取令牌if(accessLimitService.tryAcquire()){//模拟业务执行500毫秒try {Thread.sleep(500);}catch (InterruptedException e){e.printStackTrace();}return "aceess success [" + sdf.format(new Date()) + "]";}else{return "aceess limit [" + sdf.format(new Date()) + "]";}}
}
4、测试:十个线程并发访问接口
public class AccessClient {ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);/*** get请求* @param realUrl* @return*/public static String sendGet(URL realUrl) {String result = "";BufferedReader in = null;try {// 打开和URL之间的连接URLConnection connection = realUrl.openConnection();// 设置通用的请求属性connection.setRequestProperty("accept", "*/*");connection.setRequestProperty("connection", "Keep-Alive");connection.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");// 建立实际的连接connection.connect();// 定义 BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(connection.getInputStream()));String line;while ((line = in.readLine()) != null) {result += line;}} catch (Exception e) {System.out.println("发送GET请求出现异常!" + e);e.printStackTrace();}// 使用finally块来关闭输入流finally {try {if (in != null) {in.close();}} catch (Exception e2) {e2.printStackTrace();}}return result;}public void access() throws Exception{final URL url = new URL("http://localhost:8080/guavalimitdemo/access");for(int i=0;i<10;i++) {fixedThreadPool.submit(new Runnable() {public void run() {System.out.println(sendGet(url));}});}fixedThreadPool.shutdown();fixedThreadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);}public static void main(String[] args) throws Exception{AccessClient accessClient = new AccessClient();accessClient.access();}
}
部分请求由于获取的令牌可以成功执行,其余请求没有拿到令牌,我们可以根据实际业务来做区分处理。还有一点要注意,我们通过RateLimiter.create(5.0)配置的是每一秒5枚令牌,但是限流的时候发出的是6枚,改用其他值验证,也是实际的比配置的大1。
以上就是快速实现限流的实战过程,此处仅是单进程服务的限流,而实际的分布式服务中会考虑更多因素,会复杂很多。
RateLimiter方法摘要
| 修饰符和类型 | 方法和描述 |
|---|---|
| double | acquire() 从RateLimiter获取一个许可,该方法会被阻塞直到获取到请求 |
| double | acquire(int permits)从RateLimiter获取指定许可数,该方法会被阻塞直到获取到请求 |
| static RateLimiter | create(double permitsPerSecond)根据指定的稳定吞吐率创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少查询) |
| static RateLimiter | create(double permitsPerSecond, long warmupPeriod, TimeUnit unit)根据指定的稳定吞吐率和预热期来创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少个请求量),在这段预热时间内,RateLimiter每秒分配的许可数会平稳地增长直到预热期结束时达到其最大速率。(只要存在足够请求数来使其饱和) |
| double | getRate()返回RateLimiter 配置中的稳定速率,该速率单位是每秒多少许可数 |
| void | setRate(double permitsPerSecond)更新RateLimite的稳定速率,参数permitsPerSecond 由构造RateLimiter的工厂方法提供。 |
| String | toString()返回对象的字符表现形式 |
| boolean | tryAcquire()从RateLimiter 获取许可,如果该许可可以在无延迟下的情况下立即获取得到的话 |
| boolean | tryAcquire(int permits)从RateLimiter 获取许可数,如果该许可数可以在无延迟下的情况下立即获取得到的话 |
| boolean | tryAcquire(int permits, long timeout, TimeUnit unit)从RateLimiter 获取指定许可数如果该许可数可以在不超过timeout的时间内获取得到的话,或者如果无法在timeout 过期之前获取得到许可数的话,那么立即返回false (无需等待) |
| boolean | tryAcquire(long timeout, TimeUnit unit)从RateLimiter 获取许可如果该许可可以在不超过timeout的时间内获取得到的话,或者如果无法在timeout 过期之前获取得到许可的话,那么立即返回false(无需等待) |
- 举例来说明如何使用RateLimiter,想象下我们需要处理一个任务列表,但我们不希望每秒的任务提交超过两个:
//速率是每秒两个许可
final RateLimiter rateLimiter = RateLimiter.create(2.0);
void submitTasks(List tasks, Executor executor) {for (Runnable task : tasks) {rateLimiter.acquire(); // 也许需要等待executor.execute(task);}
}
官方文档:http://ifeve.com/guava-ratelimiter
相关文章:
Guava-RateLimiter详解
简介: 常用的限流算法有漏桶算法和令牌桶算法,guava的RateLimiter使用的是令牌桶算法,也就是以固定的频率向桶中放入令牌,例如一秒钟10枚令牌,实际业务在每次响应请求之前都从桶中获取令牌,只有取到令牌的请…...
【C++11】右值引用、移动构造、移动赋值、完美转发 的原理介绍
文章目录 一、概念1.1 左值1.2 左值引用1.3 什么是右值?1.4 什么是右值引用?对于参数左值还是右值的不同,是被重载支持的左值引用的使用场景 和 缺陷 二、移动语义2.1 移动拷贝构造2.2 移动赋值 三、右值引用 与 STL3.1 移动拷贝构造 和 赋值…...
Python【理解标识符的定义】
标识符是用来表示变量、函数、类、模块等命名实体的名称。它是由字母(大小写均可)、数字和下划线组成的字符串,遵循一定的命名规则和约定。以下是标识符的定义: 标识符必须以字母(大小写均可)或下划线(_)开…...
AR智能眼镜主板设计方案_AR眼镜PCB板设计
AR智能眼镜是一种采用先进技术的创新产品,具备强大的功能和性能。它采用了MTK8788八核 12nm低功耗硬件平台,搭载IMG GE830063OMhz或以上的GPU,并运行Android 11.0或以上的操作系统。该眼镜支持光波导1080P显示和LVDS接口自由曲面显示…...
【SA8295P 源码分析 (三)】79 - AIS Camera Event 事件处理函数 AisEngine::EventHandler() 源码分析
【SA8295P 源码分析】79 - AIS Camera Event 事件处理函数 AisEngine::EventHandler 源码分析 一、AIS Camera Event 事件处理函数 AisEngine::EventHandler()二、AisEngine::ProcessEvent() 函数负责处理哪些 Event 事件?三、pEngine->m_eventHandlerSignal 事件什么情况下…...
Web安全测试详解
前言 随着互联网时代的蓬勃发展,基于Web环境下的应用系统、应用软件也得到了越来越广泛的使用。 目前,很多企业的业务发展都依赖于互联网,比如,网上银行、网络购物、网络游戏等。但,由于很多恶意攻击者想通过截获他人…...
react配置 axios
配置步骤(基本配置): 1.安装 axios cnpm install axios --save2.src/utils 新建一个 request.js文件(没有utils就新建一个目录然后再建一个request.js) 3.request代码如下: 这个是最简单的配置了,你可以根据自己的需…...
【图解RabbitMQ-5】RabbitMQ Web管控台图文介绍
🧑💻作者名称:DaenCode 🎤作者简介:CSDN实力新星,后端开发两年经验,曾担任甲方技术代表,业余独自创办智源恩创网络科技工作室。会点点Java相关技术栈、帆软报表、低代码平台快速开…...
GoogleNet论文精读
论文名:Going depper with convolutions论文下载地址:https://github.com/jixiuy/paper引言第一段:背景成绩1*1的卷积在channel上升维和降维,channel融合,计算方法上等价于FNNGAP(全局平均池化)…...
智能指针shared_ptr简介及小例子
shared_ptr是一种智能指针,用于处理动态分配的对象。它提供了一种引用计数的机制,当没有任何其他shared_ptr指向一个对象时,该对象将被自动删除。 shared_ptr的作用类似于常规指针,但有一些额外的功能。它能够记录有多少个shared…...
机器人精确移动包
move_near 之前有写过, 将ROS官方的move_basic包改写成了python形式, 同时将它写成了一个完整的action接口 最近测试时发现了问题, odom的数据波动可能会导致机器人陷入正反馈从而一直移动 具体表现为: 机器人移动精度设置为0.005 [m] 机器人在移动到接近0.005的位置, odom…...
强化学习环境报错解决
问题:nameerror: name ‘glpushmatrix‘ is not defined 解决:更换pyglet包的版本。pyglet2.0a4会报这个错误,把版本换成pyglet1.5.27即可。 问题:安装了gym和ale-py但是还是找不到模型,报错ModuleNotFoundError: No…...
Ganache本地测试网如何在远程环境中进行访问和操作
文章目录 前言1. 安装Ganache2. 安装cpolar3. 创建公网地址4. 公网访问连接5. 固定公网地址 前言 Ganache 是DApp的测试网络,提供图形化界面,log日志等;智能合约部署时需要连接测试网络。 Ganache 是一个运行在本地测试的网络,通过结合cpol…...
Kotlin中的函数分类(顶层、成员、局部、递归等)
在 Kotlin 中,函数可以按照不同的方式进行分类。在本篇博客中,我们将介绍以下几种常见的函数分类,并提供示例代码进行演示。 顶层函数: 顶层函数是指定义在文件中的函数,不依赖于任何类或对象。它们可以在文件的任何…...
字符串排序程序
字符串排序程序,对一个字符串中的数值进行从小到大的排序 例如排序前给定的字符串为" 20 78 9 -7 88 36 29" 排序后: -7 9 20 29 36 78 88 要求使用包装类对数值类型的字符串转换成整型进行排序。 public class StringSort {public static vo…...
功率放大器在材料测试中的应用有哪些
功率放大器在材料测试中有广泛的应用,尤其在材料的物理、电子和热学性质等方面的研究中起到了重要的作用。下面Aigtek安泰将详细介绍功率放大器在材料测试中的一些主要应用。 电学特性测试:功率放大器用于材料的电学特性测试,如电导率、介电常…...
汽车屏类产品(一):流媒体后视镜Camera Monitoring System (CMS)
前言: CMS,有叫电子侧视镜,虚拟倒车镜,电子倒车镜, 电子取代镜等,ISO 国际标准组织称其为摄像头监控系统。电子后视镜由“摄像头+屏幕”组成,汽车外后视镜经历了光学镜面从平面镜到曲面镜的迭代进步,CMS也实现从商用车到乘用车的过渡。显示模式为外部摄像头采集图像,…...
三元组(C++ 实现矩阵快速转置)
三元组稀疏矩阵是一种高效存储稀疏矩阵的方法。它通过记录矩阵中非零元素的行、列和值来表示一个稀疏矩阵。我们在三元组里存储的是每个元素的行、列以及值。 题目: 任意输入一个稀疏矩阵M,用三元组顺序表压缩存储该稀疏矩阵M,然后求其转置矩…...
Apriori(关联规则挖掘算法)
关联规则分析 事务库 上表所示的购物篮数据即是一个事务库,该事务库记录的是用户行为的数据。 事务 上表事务库中的每一条记录被称为一笔事务。在购物篮事务中,每一次购物行为即为一笔事务,例如第一行数据“用户1购买商品A,B,C”即为一条事…...
new Object()到底占用几个字节
Java内存模型 对象内存中可以分为三块区域:对象头(Header),实例数据(Instance Data)和对齐填充(Padding),以64位操作系统为例(未开启指针压缩的情况)Java对象布局 如下图所示: 其中对象头中的Mark Word中的详细信息在文章synchr…...
3步掌握LRC歌词制作:开源工具的终极实践指南
3步掌握LRC歌词制作:开源工具的终极实践指南 【免费下载链接】lrc-maker 歌词滚动姬|可能是你所能见到的最好用的歌词制作工具 项目地址: https://gitcode.com/gh_mirrors/lr/lrc-maker 还在为制作精准同步的歌词文件而烦恼吗?传统歌词…...
IDA逆向分析实战:破解函数限制、修复栈平衡与Switch识别
1. 破解IDA函数大小限制的实战技巧 第一次用IDA反编译大型函数时,看到"function is too big"的提示真是让人头疼。这个限制其实是IDA为了防止资源耗尽设置的保险机制,但现代计算机的性能早已今非昔比。我去年分析一个游戏引擎时,核…...
Android Studio中文插件终极指南:3分钟告别英文开发环境
Android Studio中文插件终极指南:3分钟告别英文开发环境 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本) 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 还在为Androi…...
Lingtrain Aligner:如何让多语言文本对齐变得像拼图一样简单?
Lingtrain Aligner:如何让多语言文本对齐变得像拼图一样简单? 【免费下载链接】lingtrain-aligner Lingtrain Aligner — ML powered library for the accurate texts alignment. 项目地址: https://gitcode.com/gh_mirrors/li/lingtrain-aligner …...
A-29P深度解析:100dB回音消除与AI降噪的硬件设计实战
摘要:在可视门禁、车载蓝牙、远程会议等设备中,结构空间狭小与高音量需求往往导致严重的回声和啸叫问题。本文基于A-29P纯模拟回音消除模块,深入解析其100dB消回音能力、AI降噪特性及7种硬件应用模式,为工程师提供一套无需代码的快…...
网站建设公司推荐:业内公认高水准网站制作公司一览
在数字化竞争日益激烈的2026年,企业官网已从单纯的信息展示窗口升级为品牌战略核心载体与业务增长引擎。面对市场上众多的网站建设服务商,企业如何精准匹配需求?本文作为第三方深度测评,从高端定制、模板建站、低成本快速上线三类…...
强烈的“似曾相识“感:由于人类左右大脑处理信息的速度并非完全同步,在某些特殊瞬间,这个流程会被打乱
海马效应(既视现象) 目录 海马效应(既视现象) 核心科学原理 高发场景与人群 典型例子 海马效应,科学上称为既视现象(Dj vu),是指人在从未真实经历过的当下场景中,突然产生强烈的"似曾相识"感,误以为眼前的一切曾经发生过的认知错觉。它并非玄学中的"…...
Tracy安全最佳实践:开发与生产环境的安全配置指南
Tracy安全最佳实践:开发与生产环境的安全配置指南 【免费下载链接】tracy 😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI s…...
STM32F108C8T6小白入门特训营__1.4GPIO.C 代码分析
目录 1.只需要搞明白 cubemx 跟 代码对应关系就可以了 2.GPIO.C 代码加上注释 3.注意引脚的宏定义 1.只需要搞明白 cubemx 跟 代码对应关系就可以了 2.GPIO.C 代码加上注释 读懂注释部分代码即可 /* USER CODE BEGIN Header */ /*****************************************…...
AI 视频创作系统:新媒体高效增收工具,AI 自动成片,持续输出优质内容
一、新媒体行业增收难,传统创作模式遇瓶颈如今做新媒体账号想要稳定盈利,离不开高频优质内容输出。但多数从业者普遍面临诸多难题:人工写脚本耗时费力,实拍剪辑流程繁琐,长期聘请专职人员开支巨大;内容产出…...
