Guava官方文档-RateLimiter类

转载自并发编程网 – ifeve.com

RateLimiter 从概念上来讲,速率限制器会在可配置的速率下分配许可证。如果必要的话,每个acquire() 会阻塞当前线程直到许可证可用后获取该许可证。一旦获取到许可证,不需要再释放许可证。

校对注:RateLimiter使用的是一种叫令牌桶的流控算法,RateLimiter会按照一定的频率往桶里扔令牌,线程拿到令牌才能执行,比如你希望自己的应用程序QPS不要超过1000,那么RateLimiter设置1000的速率后,就会每秒往桶里扔1000个令牌。

com.google.common.util.concurrent.RateLimiter
@ThreadSafe
@Betapublic
abstract class RateLimiter extends Object

RateLimiter经常用于限制对一些物理资源或者逻辑资源的访问速率。与Semaphore 相比,Semaphore 限制了并发访问的数量而不是使用速率。(注意尽管并发性和速率是紧密相关的,比如参考Little定律

通过设置许可证的速率来定义RateLimiter。在默认配置下,许可证会在固定的速率下被分配,速率单位是每秒多少个许可证。为了确保维护配置的速率,许可会被平稳地分配,许可之间的延迟会做调整。
可能存在配置一个拥有预热期的RateLimiter 的情况,在这段时间内,每秒分配的许可数会稳定地增长直到达到稳定的速率。

举例来说明如何使用RateLimiter,想象下我们需要处理一个任务列表,但我们不希望每秒的任务提交超过两个:

//速率是每秒两个许可
final RateLimiter rateLimiter = RateLimiter.create(2.0);

void submitTasks(List tasks, Executor executor) {
    for (Runnable task : tasks) {
        rateLimiter.acquire(); // 也许需要等待
        executor.execute(task);
    }
}

再举另外一个例子,想象下我们制造了一个数据流,并希望以每秒5kb的速率处理它。可以通过要求每个字节代表一个许可,然后指定每秒5000个许可来完成:

// 每秒5000个许可
final RateLimiter rateLimiter = RateLimiter.create(5000.0); 

void submitPacket(byte[] packet) {
    rateLimiter.acquire(packet.length);
    networkService.send(packet);
}

有一点很重要,那就是请求的许可数从来不会影响到请求本身的限制(调用acquire(1) 和调用acquire(1000) 将得到相同的限制效果,如果存在这样的调用的话),但会影响下一次请求的限制,也就是说,如果一个高开销的任务抵达一个空闲的RateLimiter,它会被马上许可,但是下一个请求会经历额外的限制,从而来偿付高开销任务。注意:RateLimiter 并不提供公平性的保证。

Since:13.0  作者:   Dimitris Andreou

方法摘要

修饰符和类型 方法和描述
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(无需等待)
从java.lang.Object 类继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

方法细节

create
public static RateLimiter create(double permitsPerSecond)
根据指定的稳定吞吐率创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少查询)。
The returned RateLimiter ensures that on average no more than permitsPerSecond are issued during any given second, with sustained requests being smoothly spread over each second. When the incoming request rate exceeds permitsPerSecond the rate limiter will release one permit every (1.0 / permitsPerSecond) seconds. When the rate limiter is unused, bursts of up to permitsPerSecond permits will be allowed, with subsequent requests being smoothly limited at the stable rate of permitsPerSecond.
返回的RateLimiter 确保了在平均情况下,每秒发布的许可数不会超过permitsPerSecond,每秒钟会持续发送请求。当传入请求速率超过permitsPerSecond,速率限制器会每秒释放一个许可(1.0 / permitsPerSecond 这里是指设定了permitsPerSecond为1.0) 。当速率限制器闲置时,允许许可数暴增到permitsPerSecond,随后的请求会被平滑地限制在稳定速率permitsPerSecond中。
参数:
permitsPerSecond – 返回的RateLimiter的速率,意味着每秒有多少个许可变成有效。
抛出:
IllegalArgumentException – 如果permitsPerSecond为负数或者为0
create
public static RateLimiter create(double permitsPerSecond,long warmupPeriod,TimeUnit unit)
根据指定的稳定吞吐率和预热期来创建RateLimiter,这里的吞吐率是指每秒多少许可数(通常是指QPS,每秒多少查询),在这段预热时间内,RateLimiter每秒分配的许可数会平稳地增长直到预热期结束时达到其最大速率(只要存在足够请求数来使其饱和)。同样地,如果RateLimiter 在warmupPeriod时间内闲置不用,它将会逐步地返回冷却状态。也就是说,它会像它第一次被创建般经历同样的预热期。返回的RateLimiter 主要用于那些需要预热期的资源,这些资源实际上满足了请求(比如一个远程服务),而不是在稳定(最大)的速率下可以立即被访问的资源。返回的RateLimiter 在冷却状态下启动(即预热期将会紧跟着发生),并且如果被长期闲置不用,它将回到冷却状态。
参数:

  • permitsPerSecond – 返回的RateLimiter的速率,意味着每秒有多少个许可变成有效。
  • warmupPeriod – 在这段时间内RateLimiter会增加它的速率,在抵达它的稳定速率或者最大速率之前
  • unit – 参数warmupPeriod 的时间单位

抛出:

  • IllegalArgumentException – 如果permitsPerSecond为负数或者为0
setRate
public final void setRate(double permitsPerSecond)
更新RateLimite的稳定速率,参数permitsPerSecond 由构造RateLimiter的工厂方法提供。调用该方法后,当前限制线程不会被唤醒,因此他们不会注意到最新的速率;只有接下来的请求才会。需要注意的是,由于每次请求偿还了(通过等待,如果需要的话)上一次请求的开销,这意味着紧紧跟着的下一个请求不会被最新的速率影响到,在调用了setRate 之后;它会偿还上一次请求的开销,这个开销依赖于之前的速率。RateLimiter的行为在任何方式下都不会被改变,比如如果 RateLimiter 有20秒的预热期配置,在此方法被调用后它还是会进行20秒的预热。
参数:
permitsPerSecond – RateLimiter的新的稳定速率
抛出:
IllegalArgumentException – 如果permitsPerSecond为负数或者为0
getRate
public final double getRate()
返回RateLimiter 配置中的稳定速率,该速率单位是每秒多少许可数。它的初始值相当于构造这个RateLimiter的工厂方法中的参数permitsPerSecond ,并且只有在调用setRate(double)后才会被更新。
acquire
public double acquire()
从RateLimiter获取一个许可,该方法会被阻塞直到获取到请求。如果存在等待的情况的话,告诉调用者获取到该请求所需要的睡眠时间。该方法等同于acquire(1)。
返回:
time spent sleeping to enforce rate, in seconds; 0.0 if not rate-limited
执行速率的所需要的睡眠时间,单位为妙;如果没有则返回0
Since:
16.0 (版本13.0没有返回值)
acquire
public double acquire(int permits)
从RateLimiter获取指定许可数,该方法会被阻塞直到获取到请求数。如果存在等待的情况的话,告诉调用者获取到这些请求数所需要的睡眠时间。
参数:
permits – 需要获取的许可数
返回:
执行速率的所需要的睡眠时间,单位为妙;如果没有则返回0
抛出:
IllegalArgumentException – 如果请求的许可数为负数或者为0
Since:
16.0 (版本13.0没有返回值)
tryAcquire
public boolean tryAcquire(long timeout,TimeUnit unit)
从RateLimiter获取许可如果该许可可以在不超过timeout的时间内获取得到的话,或者如果无法在timeout 过期之前获取得到许可的话,那么立即返回false(无需等待)。该方法等同于tryAcquire(1, timeout, unit)。
参数:

  • timeout – 等待许可的最大时间,负数以0处理
  • unit – 参数timeout 的时间单位

返回:
true表示获取到许可,反之则是false
抛出:
IllegalArgumentException – 如果请求的许可数为负数或者为0

tryAcquire
public boolean tryAcquire(int permits)
从RateLimiter 获取许可数,如果该许可数可以在无延迟下的情况下立即获取得到的话。该方法等同于tryAcquire(permits, 0, anyUnit)。
参数:
permits – 需要获取的许可数
返回:
true表示获取到许可,反之则是false
抛出:
IllegalArgumentException – 如果请求的许可数为负数或者为0
Since:
14.0
tryAcquire
public boolean tryAcquire()
从RateLimiter 获取许可,如果该许可可以在无延迟下的情况下立即获取得到的话。
该方法等同于tryAcquire(1)。
返回:
true表示获取到许可,反之则是false
Since:
14.0
tryAcquire
public boolean tryAcquire(int permits,long timeout,TimeUnit unit)
从RateLimiter 获取指定许可数如果该许可数可以在不超过timeout的时间内获取得到的话,或者如果无法在timeout 过期之前获取得到许可数的话,那么立即返回false (无需等待)。
参数:
permits – 需要获取的许可数
timeout – 等待许可数的最大时间,负数以0处理
unit – 参数timeout 的时间单位
返回:
true表示获取到许可,反之则是false
抛出:
IllegalArgumentException -如果请求的许可数为负数或者为0
toString
public String toString()
以下描述复制于java.lang.Object类。
返回对象的字符表现形式。通常来讲,toString 方法返回一个“文本化呈现”对象的字符串。
结果应该是一个简明但易于读懂的信息表达式。建议所有子类都重写该方法。
toString 方法返回一个由实例的类名,字符’@’和以无符号十六进制表示的对象的哈希值组成的字符串。换句话说,该方法返回的字符串等同于:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
重载:
Object类的toString方法
返回:
对象的字符表现形式

另一篇文章:

http://xiaobaoqiu.github.io/blog/2015/07/02/ratelimiter/

 

时间: 2024-10-01 19:15:01

Guava官方文档-RateLimiter类的相关文章

python附录-builtins.py模块str类源码(含str官方文档链接)

python附录-builtins.py模块str类源码 str官方文档链接:https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str builtins.py class str(object): """ str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str Create a new stri

hbase官方文档(转)

Apache HBase™ 参考指南  HBase 官方文档中文版 Copyright © 2012 Apache Software Foundation.保留所有权利. Apache Hadoop, Hadoop, MapReduce, HDFS, Zookeeper, HBase 及 HBase项目 logo 是Apache Software Foundation的商标. Revision History Revision 0.95-SNAPSHOT 2012-12-03T13:38 中文版

Spring Cloud官方文档中文版-声明式Rest客户端:Feign

官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#spring-cloud-feign 文中例子我做了一些测试在:http://git.oschina.net/dreamingodd/spring-cloud-preparation Declarative REST Client: Feign 声明式Rest客户端:Feign Feign is a declarative web service client. It

【苦读官方文档】2.Android应用程序基本原理概述

官方文档原文地址 应用程序原理 Android应用程序是通过Java编程语言来写.Android软件开发工具把你的代码和其它数据.资源文件一起编译.打包成一个APK文件,这个文档以.apk为后缀,保存了一个Android应用程序全部的内容.Android设备通过它来安装相应的应用. 一旦安装到设备上.每一个Android应用程序就执行在各自独立的安全沙盒中: Android系统是一个多用户的Linux系统.每一个应用都是一个用户. Android系统默认会给每一个应用分配一个唯一的用户ID(这个

Spring Boot 官方文档入门及使用

个人说明:本文内容都是从为知笔记上复制过来的,样式难免走样,以后再修改吧.另外,本文可以看作官方文档的选择性的翻译(大部分),以及个人使用经验及问题. 其他说明:如果对Spring Boot没有概念,请先移步上一篇文章 Spring Boot 学习.本篇原本是为了深入了解下Spring Boot而出现的. 另外,Spring Boot 仍然是基于Spring的,建议在赶完工之后深入学习下Spring,有兴趣可以看看我的 Spring 4 官方文档学习(十一)Web MVC 框架 .欢迎探讨,笑~

OpenCV官方文档学习记录(4)

基本图形的绘制,官方文档给了一个实例,绘制下面两幅图形,分别使用了圆,椭圆,矩形,多边形,线等构造. 主要是使我们了解到如何构建这些形状,以及如何使用两种数据类型Point和Scalar分别定义点和颜色: 先放图: 完整代码如下: 1 #include <opencv2\opencv.hpp> 2 #include <iostream> 3 #include <string> 4 5 #pragma comment( linker, "/subsystem:\

Spring 4 官方文档学习(十三)集成其他web框架

重点是通用配置,非常建议看一下!有助于理解Spring的ApplicationContext与Servlet Container的关系! 1.介绍 Spring Web Flow SWF目标是成为web应用页面flow管理的最佳解决方案. SWF集成了现有的框架,如Spring MVC 和 JSF,在Servlet和Portlet环境中.如果你有一个(或多个)业务处理,且 受益于会话模型而非纯请求模型,那SWF可能就是解决方案. SWF允许捕获逻辑页面flows,并将其作为自包容的模块 -- 可

Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

在前面的文档中讲解了Spring MVC的特殊beans,以及DispatcherServlet使用的默认实现.在本部分,你会学习两种额外的方式来配置Spring MVC.分别是:MVC Java config 和  MVC XML namespace. 原文: Section 22.2.1, "Special Bean Types In the WebApplicationContext" and Section 22.2.2, "Default DispatcherSer

Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion

前言 在Spring Framework官方文档中,这三者是放到一起讲的,但没有解释为什么放到一起.大概是默认了读者都是有相关经验的人,但事实并非如此,例如我.好在闷着头看了一遍,又查资料又敲代码,总算明白了. 其实说穿了一文不值,我们用一个例子来解释: 假定,现有一个app,功能是接收你输入的生日,然后显示你的年龄.看起来app只要用当前日期减去你输入的日期就是年龄,应该很简单对吧?可惜事实不是这样的. 这里面有三个问题: 问题一:我们输入的永远是字符串,字符串需要转成日期格式才能被我们的ap