令牌桶-流量控制


  作為后台服務,通常有一個處理極限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;
    }
} 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM