令牌桶限流

通用限流方案:漏桶算法和令牌桶算法

漏桶算法

一定容量的桶存储上游的请求,以一定的速度出水,水流速度过大直接溢出。限制数据的传输速度。

令牌桶算法

除了控制流量的速度外,容忍突发暴增的传输,以稳定速度放置令牌;如果请求需要被处理,先从桶中取出令牌,如果没有令牌,拒绝服务。 

Grava令牌桶限流算法的核心实现 

/**
* @param permits 令牌桶的数量
* @param timeout 等待许可证的最长时间。负值被视为零。
* @param unit 超时参数的时间单位
**/
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) {
  long timeoutMicros = Math.max(unit.toMicros(timeout), 0L);
  checkPermits(permits);
  long microsToWait;
  synchronized(this.mutex()) {
    long nowMicros = this.stopwatch.readMicros();
    if (!this.canAcquire(nowMicros, timeoutMicros)) {
      return false;
    }

    microsToWait = this.reserveAndGetWaitLength(permits, nowMicros);
  }

  this.stopwatch.sleepMicrosUninterruptibly(microsToWait);
  return true;
}
private boolean canAcquire(long nowMicros, long timeoutMicros) {
  return this.queryEarliestAvailable(nowMicros) - timeoutMicros <= nowMicros;
}
/**
* Reserves next ticket and returns the wait time that the caller must wait for.
* 保留下一张票并返回呼叫者必须等待的等待时间。
**/
final long reserveEarliestAvailable(int requiredPermits, long nowMicros) {
  this.resync(nowMicros); //基于当前时间更新{@code storedPermits}和{@code nextFreeTicketMicros}
  long returnValue = this.nextFreeTicketMicros;
  double storedPermitsToSpend = Math.min((double)requiredPermits, this.storedPermits);
  double freshPermits = (double)requiredPermits - storedPermitsToSpend;
  long waitMicros = this.storedPermitsToWaitTime(this.storedPermits, storedPermitsToSpend) + (long)(freshPermits * this.stableIntervalMicros);
  this.nextFreeTicketMicros = LongMath.saturatedAdd(this.nextFreeTicketMicros, waitMicros);
  this.storedPermits -= storedPermitsToSpend;
  return returnValue;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值