日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

限流

每個API接口都是有訪問上限的,當訪問頻率或者并發量超過其承受范圍時候,我們就必須考慮限流來保證接口的可用性或者降級,即接口也需要安裝上保險絲,以防止非預期的請求對系統壓力過大而引起的系統癱瘓。

通常的策略就是拒絕多余的訪問,或者讓多余的訪問排隊等待服務,或者引流。

限流算法

常用的更平滑的限流算法有兩種:漏桶算法和令牌桶算法。

漏桶算法

漏桶(Leaky Bucket)算法思路很簡單,水(請求)先進入到漏桶里,漏桶以一定的速度出水(接口有響應速率),當水流入速度過大會直接溢出(訪問頻率超過接口響應速率),然后就拒絕請求,可以看出漏桶算法能強行限制數據的傳輸速率。示意圖如下:

限流算法之漏桶算法、令牌桶算法

 

可見這里有兩個變量,一個是桶的大小,支持流量突發增多時可以存多少的水(burst),另一個是水桶漏洞的大小(rate),偽代碼如下:

double rate; // leak rate in calls/s

double burst; // bucket size in calls

long refreshTime; // time for last water refresh

double water; // water count at refreshTime

refreshWater() {

long now = getTimeOfDay();

//水隨著時間流逝,不斷流走,最多就流干到0.

water = max(0, water- (now - refreshTime)*rate);

refreshTime = now;

}

bool permissionGranted() {

refreshWater();

if (water < burst) { // 水桶還沒滿,繼續加1

water ++;

return true;

} else {

return false;

}

}

因為漏桶的漏出速率是固定的參數,所以,即使網絡中不存在資源沖突(沒有發生擁塞),漏桶算法也不能使流突發(burst)到端口速率。因此,漏桶算法對于存在突發特性的流量來說缺乏效率。

令牌桶算法

令牌桶算法(Token Bucket)和 Leaky Bucket 效果一樣,但方向相反的算法。隨著時間流逝,系統會按恒定1/QPS時間間隔(如果QPS=100,則間隔是10ms)往桶里加入Token(想象和漏洞漏水相反,有個水龍頭在不斷的加水),如果桶已經滿了就不再加了。新請求來臨時,會各自拿走一個Token,如果沒有Token可拿了就阻塞或者拒絕服務。

限流算法之漏桶算法、令牌桶算法

 

大小固定的令牌桶可自行以恒定的速率源源不斷地產生令牌。如果令牌不被消耗,或者被消耗的速度小于產生的速度,令牌就會不斷地增多,直到把桶填滿。后面再產生的令牌就會從桶中溢出。最后桶中可以保存的最大令牌數永遠不會超過桶的大小。

傳送到令牌桶的數據包需要消耗令牌。不同大小的數據包,消耗的令牌數量不一樣。

令牌桶這種控制機制基于令牌桶中是否存在令牌來指示什么時候可以發送流量。令牌桶中的每一個令牌都代表一個字節。如果令牌桶中存在令牌,則允許發送流量;而如果令牌桶中不存在令牌,則不允許發送流量。因此,如果突發門限被合理地配置并且令牌桶中有足夠的令牌,那么流量就可以以峰值速率發送。

Guava RateLimiter 簡介

google開源工具包Guava提供了限流工具類RateLimiter,該類基于令牌桶算法(Token Bucket)來完成限流,非常易于使用。RateLimiter經常用于限制對一些物理資源或者邏輯資源的訪問速率。它支持兩種獲取permits接口,一種是如果拿不到立刻返回false,一種會阻塞等待一段時間看能不能拿到。

RateLimiter和JAVA中的信號量(java.util.concurrent.Semaphore)類似,Semaphore通常用于限制并發量。

源碼中的一個例子,比如我們有很多任務需要執行,但是我們不希望每秒超過兩個任務執行,那么我們就可以使用RateLimiter:

final RateLimiter rateLimiter = RateLimiter.create(2.0);

void submitTasks(List<Runnable> tasks, Executor executor) {

for (Runnable task : tasks) {

rateLimiter.acquire(); // may wait

executor.execute(task);

}

}

另外一個例子,假如我們會產生一個數據流,然后我們想以每秒5kb的速度發送出去。我們可以每獲取一個令牌(permit)就發送一個byte的數據,這樣我們就可以通過一個每秒5000個令牌的RateLimiter來實現:

final RateLimiter rateLimiter = RateLimiter.create(5000.0);

void submitPacket(byte[] packet) {

rateLimiter.acquire(packet.length);

networkService.send(packet);

}

另外,我們也可以使用非阻塞的形式達到降級運行的目的,即使用非阻塞的tryAcquire()方法:

if(limiter.tryAcquire()) { //未請求到limiter則立即返回false

doSomething();

}else{

doSomethingElse();

}

漏桶算法和令牌桶算法的選擇

漏桶算法與令牌桶算法在表面看起來類似,很容易將兩者混淆。但事實上,這兩者具有截然不同的特性,且為不同的目的而使用。

漏桶算法與令牌桶算法的區別在于,漏桶算法能夠強行限制數據的傳輸速率,令牌桶算法能夠在限制數據的平均傳輸速率的同時還允許某種程度的突發傳輸。

需要注意的是,在某些情況下,漏桶算法不能夠有效地使用網絡資源,因為漏桶的漏出速率是固定的,所以即使網絡中沒有發生擁塞,漏桶算法也不能使某一個單獨的數據流達到端口速率。因此,漏桶算法對于存在突發特性的流量來說缺乏效率。而令牌桶算法則能夠滿足這些具有突發特性的流量。通常,漏桶算法與令牌桶算法結合起來為網絡流量提供更高效的控制。

分享到:
標簽:算法
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定