并发编程案例:高性能限流器Guava RateLimiter

本文介绍了Guava RateLimiter的使用和实现原理,通过令牌桶算法进行限流,避免高并发导致系统不稳定。Guava的实现避免了定时器在高并发场景下的精度误差和性能影响,通过记录并动态计算下一令牌发放时间来完成限流功能。
摘要由CSDN通过智能技术生成

Guava 是Google 开源的 Java 类库,提供了一个工具类 RateLimiter。我们先来看看 RateLimiter的使用,让你对限流有个感官的印象。假设我们有一个线程池,它每秒只能处理两个任务,如果提交的任务过快,可能导致系统不稳定,这个时候就需要用到限流。

在下面的示例代码中,我们创建了一个流速为 2 个请求 / 秒的限流器,这里的流速该怎么理解呢?直观地看,2 个请求 / 秒指的是每秒最多允许 2 个请求通过限流器,其实在Guava中,流速还有更深一层的意思:是一种匀速的概念,2 个请求 / 秒等价于 1 个请求/500 毫秒。

在向线程池提交任务之前,调用 acquire() 方法就能起到限流的作用。通过示例代码的执行结果,任务提交到线程池的时间间隔基本上稳定在 500 毫秒。

/* 限流器流速:2 个请求 / 秒 2 RateLimiter limiter = */
RateLimiter.create( 2.0 );
/* 执行任务的线程池 */
ExecutorService es = Executors
		     .newFixedThreadPool( 1 );
/* 记录上一次执行时间 */
prev = System.nanoTime();
/* 测试执行 20 次 */
for ( int i = 0; i < 20; i++ )
{
	/* 限流器限流 */
	limiter.acquire();
	/* 提交任务异步执行 */
	es.execute( () - > {
			    long cur = System.nanoTime();
	                    /* 打印时间间隔:毫秒 */
			    System.out.println(
				    (cur - prev) / 1000_000 );
			    prev = cur;
		    } );
}

输出结果 :
...
500
499
499
500
499

经典限流算法:令牌桶算法

Guava 的限流器使用上还是很简单的,那它是如何实现的呢?Guava 采用的是令牌桶算法,其核心是要想通过限流器,必须拿到令牌。也就是说,只要我们能够限制发放令牌的速率,那么就能控制流速了。令牌桶算法的详细描述如下:

  1. 令牌以固定的速率添加到令牌桶中,假设限流的速率是 r/ 秒,则令牌每 1/r 秒会添加一个;
  2. 假设令牌桶的容量是 b ,如果令牌桶已满,则新的令牌会被丢弃;
  3. 请求能够通过限流器的前提是令牌桶中有令牌。

这个算法中,限流的速率 r 还是比较容易理解的,但令牌桶的容量 b 该怎么理解呢?b 其实是 burst 的简写,意义是限流器允许的最大突发流量

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值