流控

2017/03/24 infra 微服务

服务化过程中各种流控策略

计数器

计数器

滑动窗口

滑动窗口

控制并发

信号量

Semaphore semphore = new Semaphore(10);  
  if(semphore.getQueueLength() > 10){  
   //等待队列阀值为10时  
    return;  
  }  
  try {  
   semphore.acquire();  

   //干活  

  } catch (InterruptedException e) {  
       e.printStackTrace();  
  }finally{  
     semphore.release();//释放  
  }

控制速率

令牌桶

令牌桶

在 Wikipedia 上,令牌桶算法是这么描述的:

  • 每秒会有 r 个令牌放入桶中,或者说,每过 1/r 秒桶中增加一个令牌
  • 桶中最多存放 b 个令牌,如果桶满了,新放入的令牌会被丢弃
  • 当一个 n 字节的数据包到达时,消耗 n 个令牌,然后发送该数据包
  • 如果桶中可用令牌小于 n,则该数据包将被缓存或丢弃

令牌桶控制的是一个时间窗口内的通过的数据量,在 API 层面我们常说的 QPS、TPS,正好是一个时间窗口内的请求量或者事务量,只不过时间窗口限定在 1s 罢了。Java 语言,可以借助 Guava 的 RateLimiter 来实现基于令牌桶的流控。RateLimiter 对简单的令牌桶算法做了一些工程上的优化,具体的实现是 SmoothBursty。SmoothBursty 有一个可以放 N 个时间窗口产生的令牌的桶,系统空闲的时候令牌就一直攒着,最好情况下可以扛 N 倍于限流值的高峰而不影响后续请求。RateLimiter 允许某次请求拿走超出剩余令牌数的令牌,但是下一次请求将为此付出代价,一直等到令牌亏空补上,并且桶中有足够本次请求使用的令牌为止。

需要注意的是,RateLimiter 的另一个实现 SmoothWarmingUp,就不是令牌桶了,而是漏桶算法。

出于简单起见,RateLimiter 中的时间窗口能且仅能为 1s,如果想搞其他时间单位的限流,只能另外造轮子。

漏桶

漏桶

  • “漏桶算法”能够强行限制数据的传输速率,
  • “令牌桶算法”在能够限制数据的平均传输数据外,还允许某种程度的突发传输。在“令牌桶算法”中,只要令牌桶中存在令牌,那么就允许突发地传输数据直到达到用户配置的上限,因此它适合于具有突发特性的流量。

Search

    Table of Contents