- Guava RateLimit SmoothBurst 支持特定时间内限流,但是问题是突发时还是容易造成服务端压力
- Guava RateLimit SmoothWarmingUp 通过设置一个预热的过程,达到速度后会趋向于平均速度限流。
import com.google.common.util.concurrent.RateLimiter;
public class RateLimitToolTest {
public static void main(String[] args) throws InterruptedException {
test3();
}
// SmoothyBurst
private static void test() {
RateLimiter limiter = RateLimiter.create(5);
// limiter.acquire() 返回获取操作的耗时,以秒为单位
System.out.println(limiter.acquire());
System.out.println(limiter.acquire());
System.out.println(limiter.acquire());
System.out.println(limiter.acquire());
System.out.println(limiter.acquire());
System.out.println(limiter.acquire());
}
public static void test1() {
// 每秒允许5个请求,表示桶容量为5且每秒新增5个令牌,即每隔0.2毫秒新增一个令牌
RateLimiter limiter = RateLimiter.create(5);
// 一次性消费5个令牌
System.out.println(limiter.acquire(5));
// limiter.acquire(1)将等待差不多1秒桶中才能有令牌
System.out.println(limiter.acquire(1));
// 固定速率
System.out.println(limiter.acquire(1));
// 固定速率
System.out.println(limiter.acquire(1));
// 固定速率
System.out.println(limiter.acquire(1));
}
public static void test2() throws InterruptedException {
// 每秒允许5个请求,表示桶容量为5且每秒新增5个令牌,即每隔0.2毫秒新增一个令牌
RateLimiter limiter = RateLimiter.create(200);
long start = System.currentTimeMillis();
TimeUnit.SECONDS.sleep(2);
for (int i = 1; i <= 1000; i++) {
// 第一秒突发了10个请求
limiter.acquire(1);
if (i % 100 == 0) {
System.out.println("Spend " + (System.currentTimeMillis() - start) + " ms");
}
}
}
public static void test3() throws InterruptedException {
RateLimiter limiter = RateLimiter.create(200);
TimeUnit.SECONDS.sleep(1);
long start = System.currentTimeMillis();
for(int i =1; i < 500;i++) {
System.out.println(limiter.acquire());
}
long point = System.currentTimeMillis();
System.out.println("Spend " + (point - start));
Thread.sleep(1000L);
for(int i =1; i < 500;i++) {
System.out.println(limiter.acquire());
}
System.out.println("Spend " + (point - start));
}
// SmoothWarmingUp
public static void test4() throws InterruptedException {
RateLimiter limiter = RateLimiter.create(200,1000, TimeUnit.MILLISECONDS);
TimeUnit.SECONDS.sleep(1);
long start = System.currentTimeMillis();
for(int i =1; i < 500;i++) {
System.out.println(limiter.acquire());
}
long point = System.currentTimeMillis();
System.out.println("Spend " + (point - start));
Thread.sleep(1000L);
for(int i =1; i < 500;i++) {
System.out.println(limiter.acquire());
}
System.out.println("Spend " + (point - start));
}
}
复制代码
转载于:https://juejin.im/post/5c88a2dde51d455e4d7193b1