Guava RateLimiter
Guava RateLimiter原理
Guava RateLimiter基于令牌桶算法,我们只需要告诉RateLimiter系统限制的QPS是多少,那么RateLimiter将以这个速度往桶里面放入令牌,然后请求的时候,通过tryAcquire()方法向RateLimiter获取许可(令牌)。
API说明
// 每过permitsPerSecond秒钟创建一个令牌
public static RateLimiter create(double permitsPerSecond) {
return create(permitsPerSecond, RateLimiter.SleepingStopwatch.createFromSystemTimer());
}
// 获取permits个许可花费的时间
public double acquire(int permits) {
long microsToWait = this.reserve(permits);
this.stopwatch.sleepMicrosUninterruptibly(microsToWait);
return 1.0D * (double)microsToWait / (double)TimeUnit.SECONDS.toMicros(1L);
}
// 尝试能否在timeout时间内获取permits个许可,获取成功返回true,否则false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) {
... ...
}
demo
- acquire
import com.google.common.util.concurrent.RateLimiter;
public class RateLimterTest {
private RateLimiter rateLimiter = RateLimiter.create(1);
public static void main(String[] args) {
RateLimterTest rateLimterTest = new RateLimterTest();
for (int i = 0; i < 1000; i++) {
double waitTime = rateLimterTest.rateLimiter.acquire();
System.out.println("waitTime:" + waitTime);
}
}
}
<====
waitTime:0.0
waitTime:0.99648
waitTime:0.99457
waitTime:0.997249
waitTime:0.997921
waitTime:0.998888
- tryAcquire
import com.google.common.util.concurrent.RateLimiter;
import java.util.concurrent.TimeUnit;
public class RateLimterTest {
private RateLimiter rateLimiter = RateLimiter.create(1);
public static void main(String[] args) {
RateLimterTest rateLimterTest = new RateLimterTest();
while(true) {
if (rateLimterTest.rateLimiter.tryAcquire(1, 1/2, TimeUnit.SECONDS)) {
System.out.println("到你了");
} else {
System.out.println("还没到你");
}
}
}
}
参考
【1】超详细的Guava RateLimiter限流原理解析:https://zhuanlan.zhihu.com/p/60979444
【2】guava的限流工具RateLimiter使用
【3】guava maven:https://mvnrepository.com/artifact/com.google.guava/guava
【4】高并发之限流RateLimiter(二)
【5】限流工具RateLimiter:https://blog.csdn.net/weixin_38336658/article/details/83819691
网友评论