關於兩種限流模式

2022-07-25 06:18:09 字數 2744 閱讀 9605

流量預警和限流方案中,比較常用的有兩種。第一種滑窗模式,通過統計一段時間內的訪問次數來進行控制,訪問次數達到的某個峰值時進行限流。第二種為併發使用者數模式,通過控制最大併發使用者數,來達到流量控制的目的。下面來簡單分析下兩種的優缺點。

1、滑窗模式

模式分析:

在每次有訪問進來時,我們判斷前n個單位時間內的總訪問量是否超過了設定的閾值,並對當前時間片上的請求數+1。

上圖每乙個格式表示乙個固定的時間(比如1s),每個格仔乙個計數器,我們要獲取前5s的請求量,就是對當前時間片i ~ i-4的時間片上計數器進行累加。

這種模式的實現的方式更加契合流控的本質意義。理解較為簡單。但由於訪問量的不可預見性,會發生單位時間的前半段大量請求湧入,而後半段則拒絕所有請求的情況。(通常,需要可以將單位時間切的足夠的小來緩解 )其次,我們很難確定這個閾值設定在多少比較合適,只能通過經驗或者模擬(如壓測)來進行估計,即使是壓測也很難估計的準確。集群部署中每台機器的硬體引數不同,可能導致我們需要對每台機器的閾值設定的都不盡相同。同一臺機子在不同的時間點的系統壓力也不一樣(比如晚上還有一些任務,或其他的一些業務操作的影響),能夠承受的最大閾值也不盡相同,我們無法考慮的周全。

所以滑窗模式通常適用於對某一資源的保護的需求上(或者說是承諾比較合適:我對某一介面的提供者承諾過,最高呼叫量不超過xx),如對db的保護,對某一服務的呼叫的控制上。

**實現思路:

每乙個時間片(單位時間)就是乙個獨立的計數器,用以陣列儲存。將當前時間以某種方式(比如取模)對映到陣列的一項中。每次訪問先對當前時間片上的計數器+1,再計算前n個時間片的訪問量總合,超過閾值則限流。

/**

* 滑窗的實現

* @author shimig

* */

public class slidingwindow

/*** 初始化佇列,由於此初始化會申請一些內容空間,為了節省空間,延遲初始化

*/private void inittimeslices()

// 在多執行緒的情況下,會出現多次初始化的情況,沒關係

// 我們只需要保證,獲取到的值一定是乙個穩定的,所有這裡使用先初始化,最後賦值的方法

atomicinteger localtimeslices = new atomicinteger[timeslicesize];

for (int i = 0; i < timeslicesize; i++)

timeslices = localtimeslices; }

private int locationindex()

/*** 對時間片計數+1,並返回視窗中所有的計數總和

* 該方法只要呼叫就一定會對某個時間片進行+1

* * @return

*/public int incrementandsum() else

for (int i = 1; i < windowsize; i++)

return sum; }

/*** 判斷是否允許進行訪問,未超過閾值的話才會對某個時間片+1

* * @param threshold

* @return

*/public boolean allow(int threshold)

for (int i = 1; i < windowsize; i++)

// 閾值判斷

if (sum <= threshold)

return false; }

/*** 將fromindex~toindex之間的時間片計數都清零

* 極端情況下,當迴圈佇列已經走了超過1個timeslicesize以上,這裡的清零並不能如期望的進行

* * @param fromindex 不包含

* @param toindex 不包含

*/private void clearbetween(int fromindex, int toindex) }

}

2、併發使用者數模式模式分析:每次操作執行時,我們通過判斷當前正在執行的訪問數是否超過某個閾值在決定是否限流。

該模式看著思路比較的另類,但卻有其獨到之處。實際上我們限流的根本是為了保護資源,防止系統接受的請求過多,應接不暇,拖慢系統中其他介面的服務,造成雪崩。我們真正需要關心的是那些執行中的請求,而那些已經完成的請求已是過去時,不再是需要關心的了。

我們來看看其閾值的計算方式,對於乙個請求來說,響應時間rt、qps是乙個比較容易獲取的引數,那麼我們這樣計算:qps/1000*rt。

此外,乙個應用往往是個複雜的系統,提供的服務或者暴露的請求、資源不止乙個。內部gc、定時任務的執行、其他服務訪問的驟增,外部依賴方、db的抖動,抑或是**中不經意間的乙個bug。都可能導致響應時間的變化,導致系統效能容量的改變 。而這種模式,則能恰如其分的自動做出調整,當系統不適時,rt增加,會自動的對qps做出適應。

**實現思路:

當訪問開始時,我們對當前計數器(原子計數器)+1,當完成時,-1。該計數器即為當前正在執行的請求數。只需判斷這個計數器是否超過閾值即可。

<

iteye推薦

Nginx 中的兩種限流方式

nginx 提供兩種限流方式,一是控制速率,二是控制併發連線數。下面例子使用 nginx limit req zone 和 limit req 兩個指令,限制單個ip的請求處理速率。在 nginx.conf http 中新增限流配置 http配置server,使用limit req指令應用限流。se...

關於FTP的兩種連線模式

我對於ftp這方面的知識比較薄弱,最近在實習的時候剛好有需要去了解,所以想寫下來整理一下,如果有不對的地方望指正。ftp服務一般執行在20和21兩個埠。一次完整的 ftp 會話,包含有兩個連線,乙個稱之為命令通道 控制連線,通過21埠 乙個稱之為資料通道 資料連線,通過20埠 其中資料連線有兩種傳輸...

EPOLL兩種模式

select epoll 的特點 select 的特點 select 選擇控制代碼的時候,是遍歷所有控制代碼,也就是說控制代碼有事件響應時,select 需要遍歷所有控制代碼才能獲取到哪些控制代碼有事件通知,因此效率是非常低。但是如果連線很少的情況下,select 和epoll的lt 觸發模式相比,...