给接口上“保险丝”(rate-limiter)

给接口上“保险丝”(rate-limiter)


可能到来的某天

某系统接口的请求量暴增,继而接口不可用,并引发连锁反应导致整个系统不能正常服务。

优化程序执行效率?换更power的机器?扩大集群?

无论系统接口处理能力多强,也难免会有请求方突发性或者无限制性调用,导致系统接口崩溃。所以,在接口能力满足预期业务下,给接口上“保险丝”(限流),是系统持续稳定、自我保护的一个机制。

如何限流

控制好接口单位时间内的请求数(QPS/TPS)。

系统上线前,一般都需要对系统进行压测,确认系统吞吐量或者各个接口的处理能力。我们可以根据测试报告,对系统每个接口设定rate进行限流(当然,也可以细化粒度,针对调用方和调用接口限流,有点像公共api接口或者能力平台接口的接口调用限制)

如何实现限流

计数器(简单粗暴)

简单维护一个单位时内的计数器,请求过来则递增,计算器过期则清理。

计数器示意图

伪代码:

long timeStamp=getNowTime();
int reqCount=0;
const int rate=100;//时间周期内最大请求数
const long interval=1000;//时间控制周期ms

bool grant(){
    long now=getNowTime();
    if (now <timeStamp+interval){//在时间控制范围内
        reqCount++;
        return reqCount>rate;//当前时间范围内超过最大请求控制数
    }else{
        timeStamp=now;//超时后重置
        reqCount=0;
        return true;
    }
}

漏桶算法(Leaky Bucket)

水(请求)先进入到漏桶里,漏桶以恒定的速度出水,当水流入速度过大会导致溢出。

漏桶算法示意图

伪代码:

long timeStamp=getNowTime();        
int capacity;        // 桶的容量
int rate ;          //水漏出的速度
int water;          //当前水量

bool grant() {
  //先执行漏水,因为rate是固定的,所以可以认为“时间间隔*rate”即为漏出的水量
  long  now = getNowTime();
  water = max(0, water- (now - timeStamp)*rate);
  timeStamp = now;

  if (water < capacity) { // 水还未满,加水
    water ++;
    return true;
  } else {
    return false;//水满,拒绝加水
  }
}

令牌桶算法(Token Bucket)

以恒定速度往桶里放入Token,请求过来需从桶里获取Token,当请求速度过大会导致获取Token失败。

令牌桶算法示意图

Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法来完成限流

伪代码

long timeStamp=getNowTime();        
int capacity;              // 桶的容量
int rate ;              //令牌放入速度
int tokens;            //当前水量

bool grant() {
  //先执行添加令牌的操作
  long  now = getNowTime();
  tokens = max(capacity, tokens+ (now - timeStamp)*rate);
  timeStamp = now;
  //令牌已用完,拒绝访问
  if(tokens<1){
    return false;
  }else{//还有令牌,领取令牌
    tokens--;
    retun true;
  }
}

其他算法

基于上述计数器方式,将单位时间切割到更小的时间片,每个时间片维护一个计数器,随着时间推送,清理单位时间外的所有计数器,统计当前单位时间内的所有计数器。

其他算法示意图

参考

  1. http://colobu.com/2014/11/13/rate-limiting/
  2. http://www.cnblogs.com/LBSer/p/4083131.html
  3. docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
  4. http://en.wikipedia.org/wiki/Leaky_bucket
  5. http://sharecore.net/2014/06/21/%E8%BF%87%E8%BD%BD%E4%BF%9D%E6%8A%A4%E7%AE%97%E6%B3%95%E6%B5%85%E6%9E%90/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值