guava----RateLimiter限流工具

目录

  • 推荐公众号
  • 前言
  • 使用
  • 过程分析
  • 总结

推荐公众号

有彩蛋哦!!!(或者公众号内点击网赚获取彩蛋)
程序员探索之路

前言

在调用第三方接口的时候一般都会有接口调用频率限制,如果一般的不频繁的业务情况我们不需要业务处理,但是如果遇到批量调用的情况就需要考虑怎么做限制了。谷歌guava工具的RateLimiter提供了限流,采用的是令牌桶算法

使用

@Slf4j
public class RateLimitService {
    private static final ExecutorService rateLimitPool = Executors.newFixedThreadPool(30);
    private static final RateLimiter rateLimiter = RateLimiter.create(20);
    private static final int ALL_TASK = 100;
    public static void testRateLimit(){
        for (int i = 0;i < ALL_TASK;i++){
            rateLimitPool.execute(()->{
                rateLimiter.acquire();
                try {
                    log.info("take a token");
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }
    }

    public static void main(String[] args) {
        testRateLimit();
    }
}
结果:
33 1334 2021:33:33.458 [pool-1-thread-2] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.458 [pool-1-thread-8] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.465 [pool-1-thread-5] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.515 [pool-1-thread-4] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.565 [pool-1-thread-1] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.615 [pool-1-thread-24] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.664 [pool-1-thread-9] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.715 [pool-1-thread-12] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.765 [pool-1-thread-6] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.814 [pool-1-thread-7] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.865 [pool-1-thread-13] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.914 [pool-1-thread-16] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:33.965 [pool-1-thread-17] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.014 [pool-1-thread-10] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.064 [pool-1-thread-11] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.115 [pool-1-thread-20] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.164 [pool-1-thread-21] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.215 [pool-1-thread-3] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.264 [pool-1-thread-25] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.314 [pool-1-thread-28] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.364 [pool-1-thread-14] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.414 [pool-1-thread-15] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.465 [pool-1-thread-18] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.515 [pool-1-thread-19] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.563 [pool-1-thread-22] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.614 [pool-1-thread-23] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.664 [pool-1-thread-26] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.714 [pool-1-thread-27] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.764 [pool-1-thread-30] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.815 [pool-1-thread-29] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.865 [pool-1-thread-2] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.914 [pool-1-thread-8] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:34.964 [pool-1-thread-5] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.014 [pool-1-thread-4] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.064 [pool-1-thread-1] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.115 [pool-1-thread-24] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.165 [pool-1-thread-9] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.215 [pool-1-thread-12] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.265 [pool-1-thread-6] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.315 [pool-1-thread-7] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.365 [pool-1-thread-13] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.414 [pool-1-thread-16] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.465 [pool-1-thread-17] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.515 [pool-1-thread-10] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.565 [pool-1-thread-11] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.615 [pool-1-thread-20] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.665 [pool-1-thread-21] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.715 [pool-1-thread-3] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.764 [pool-1-thread-25] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.814 [pool-1-thread-28] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.865 [pool-1-thread-14] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.914 [pool-1-thread-15] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:35.965 [pool-1-thread-18] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.015 [pool-1-thread-19] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.067 [pool-1-thread-22] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.115 [pool-1-thread-23] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.164 [pool-1-thread-26] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.214 [pool-1-thread-27] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.264 [pool-1-thread-30] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.314 [pool-1-thread-29] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.365 [pool-1-thread-2] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.415 [pool-1-thread-8] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.465 [pool-1-thread-5] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.514 [pool-1-thread-4] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.564 [pool-1-thread-1] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.614 [pool-1-thread-24] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.664 [pool-1-thread-9] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.715 [pool-1-thread-12] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.765 [pool-1-thread-6] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.815 [pool-1-thread-7] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.865 [pool-1-thread-13] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.914 [pool-1-thread-16] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:36.964 [pool-1-thread-17] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.014 [pool-1-thread-10] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.065 [pool-1-thread-11] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.115 [pool-1-thread-20] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.165 [pool-1-thread-21] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.215 [pool-1-thread-3] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.264 [pool-1-thread-25] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.314 [pool-1-thread-28] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.364 [pool-1-thread-14] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.414 [pool-1-thread-15] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.464 [pool-1-thread-18] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.515 [pool-1-thread-19] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.565 [pool-1-thread-22] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.615 [pool-1-thread-23] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.664 [pool-1-thread-26] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.714 [pool-1-thread-27] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.764 [pool-1-thread-30] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.815 [pool-1-thread-29] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.865 [pool-1-thread-2] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.915 [pool-1-thread-8] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:37.965 [pool-1-thread-5] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.014 [pool-1-thread-4] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.065 [pool-1-thread-1] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.114 [pool-1-thread-24] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.164 [pool-1-thread-9] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.215 [pool-1-thread-12] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.265 [pool-1-thread-6] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token
21:33:38.315 [pool-1-thread-7] INFO com.zzh.rocket.serverall.service.RateLimitService - take a token

过程分析

  返回睡的毫秒数
  @CanIgnoreReturnValue
  public double acquire() {
    return acquire(1);
  }
   @CanIgnoreReturnValue
  public double acquire(int permits) {
    获取需要等待多少秒
    long microsToWait = reserve(permits);
    如果等待毫秒数 > 0  就调用Thread.sleep
    stopwatch.sleepMicrosUninterruptibly(microsToWait);
    返回等待的毫秒数
    return 1.0 * microsToWait / SECONDS.toMicros(1L);
  }

-----判断sleep代码
		@Override
        protected void sleepMicrosUninterruptibly(long micros) {
          if (micros > 0) {
            Uninterruptibles.sleepUninterruptibly(micros, MICROSECONDS);
          }
        }
public static void sleepUninterruptibly(long sleepFor, TimeUnit unit) {
    boolean interrupted = false;
    try {
      long remainingNanos = unit.toNanos(sleepFor);
      long end = System.nanoTime() + remainingNanos;
      while (true) {
        try {
          // TimeUnit.sleep() treats negative timeouts just like zero.
          NANOSECONDS.sleep(remainingNanos);
          return;
        } catch (InterruptedException e) {
          interrupted = true;
          remainingNanos = end - System.nanoTime();
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }
  public void sleep(long timeout) throws InterruptedException {
        if (timeout > 0) {
            long ms = toMillis(timeout);
            int ns = excessNanos(timeout, ms);
            Thread.sleep(ms, ns);
        }
    }

总结

只大致看了一下流程,RateLimiter还有很多细节,比如实现类有两个,还有tryAcquire方法返回是否拿到令牌,后面还需要分析源码

你可能感兴趣的:(guava)