令牌桶-流量控制

  作为后台服务,通常有一个处理极限PPS(packets per second),如果请求超过了这个处理能力,可能会出现“雪崩效应”,因此后台服务需要有过载保护机制。

1、有个简单的算法可以实现流量控制功能:设置一个单位时间(如1s, 1min)内的最大访问量,并维护一个单位时间里的计数器。

当访问请求到达时,先判断单位控制时间是否已经超时,如果已经超时,重置计数器为0;

否则,将计数器加1,并判断计数器的值是否超过最大访问量设置,如超过,则拒绝访问。

伪代码如下:

 1 long timeStamp=getNowTime();
 2 int reqCount=0;
 3 const int maxReqCount=10000;//时间周期内最大请求数
 4 const long effectiveDuration=10;//时间控制周期
 5 
 6 bool grant()
 7 {
 8     long now=getNowTime();
 9     if (now <timeStamp+effectiveDuration)
10     {
11         //在时间控制范围内
12         reqCount++;
13         return reqCount>maxReqCount;//当前时间范围内超过最大请求控制数
14     }
15     else
16     {
17         timeStamp=now;//超时后重置
18         reqCount=0;
19         return true;
20     } 
21 }

该算法实现确实是实现了“单位时间里最大访问量控制”这一需求,但是,仔细研究下,发现它在两个单位时间的临界值上的处理是有缺陷的。

如:设需要控制的最大请求数为1w, 在第一个单位时间的最后一秒里达到的请求数为1w,接下来第二个单位时间内的第一秒里达到请求数也是1w,由于超时重置发生在两个单位时间之间,

所以这2w个请求都将通过控制,也就是说在2s里处理2w个请求,与我们设置的10s里1w个请求的需求相违背。

 

2、令牌桶算法

                                     

令牌桶算法的原理是系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。从原理上看,令牌桶算法和漏桶算法是相反的,一个“进水”,一个是“漏水”。

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

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

转载于:https://www.cnblogs.com/ym65536/p/5041309.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值