在開發高併發系統時,有三把利器來保護系統:快取、降級和限流。下面來看看限流量的一些演算法:
1.計數器法:
它是限流演算法中最簡單最容易的一種演算法,比如我們要求某乙個介面,1分鐘內的請求不能超過10次,我們可以在開始時設定乙個計數器,
每次請求,該計數器+1;如果該計數器的值大於10並且與第一次請求的時間間隔在1分鐘內,那麼說明請求過多;如果該請求與第一次請求
的時間間隔大於1分鐘,並且該計數器的值還在限流範圍內,那麼重置該計數器。具體**如下:
public class counterdemo
else }}
不過,以上**有致命問題,當遇到惡意請求,在0:59時,瞬間請求100次,並且在1:00請求100次,那麼這個使用者在1秒內請求了200次,
使用者可以在重置節點突發請求,而瞬間超過我們設定的速率限制,使用者可能通過演算法漏洞擊垮我們的應用。如下圖,如何解決呢,看下邊的滑動視窗演算法。
2.滑動視窗演算法:
在上圖中,整個紅色矩形框是乙個時間視窗,在我們的例子中,乙個時間視窗就是1分鐘,然後我們將時間視窗進行劃分,如上圖我們把滑動視窗
劃分為6格,所以每一格代表10秒,每超過10秒,我們的時間視窗就會向右滑動一格,每一格都有自己獨立的計數器,例如:乙個請求在0:35到達,
那麼0:30到0:39的計數器會+1,那麼滑動視窗是怎麼解決臨界點的問題呢?如上圖,0:59到達的100個請求會在灰色區域格仔中,而1:00到達的請求
會在紅色格仔中,視窗會向右滑動一格,那麼此時間視窗內的總請求數共200個,超過了限定的100,所以此時能夠檢測出來觸發了限流。
回頭看看計數器演算法,會發現,其實計數器演算法就是視窗滑動演算法,只不過計數器演算法沒有對時間視窗進行劃分,所以是一格。
由此可見,當滑動視窗的格仔劃分越多,限流的統計就會越精確。
3.漏桶演算法:
漏桶演算法,又稱 leaky bucket ,如下圖:
這個演算法很簡單。首先,我們有乙個固定容量的桶,有水進來,也有水出去。對於流進來的水,我們無法預計共有多少水流進來,也無法預計流水速度,但
對於流出去的水來說,這個桶可以固定水流的速率,而且當桶滿的時候,多餘的水會溢位來。
public class leakydemo
else }}
4.令牌桶演算法:
又稱token bucket,如下圖:
從上圖中可以看出,令牌演算法有點複雜,桶裡存放著令牌token。桶一開始是空的,token以固定的速率r往桶裡面填充,直到達到桶的容量,多餘的token會
被丟棄。每當乙個請求過來時,就會嘗試著移除乙個token,如果沒有token,請求無法通過。
public class tokenbucketdemo
else }}
計數器演算法是最簡單的演算法,可以看成是滑動視窗的低精度實現。滑動視窗由於需要儲存多份的計數器(每乙個格仔存乙份),所以滑動視窗在實現上需要更多的儲存空間。也就是說,如果滑動視窗的精度越高,需要的儲存空間就越大。
漏桶演算法和令牌桶演算法最明顯的區別是令牌桶演算法允許流量一定程度的突發。因為預設的令牌桶演算法,取走token是不需要耗費時間的,也就是說,假設桶內有100個token時,那麼可以瞬間允許100個請求通過。
令牌桶演算法由於實現簡單,且允許某些流量的突發,對使用者友好,所以被業界採用地較多。當然我們需要具體情況具體分析,只有最合適的演算法,沒有最優的演算法。
原文:
介面限流演算法小記
高併發系統中保護系統的三把利器 快取 降級 限流 快取 快取的目的是提公升系統訪問速度和增大系統處理容量 降級 降級是當伺服器壓力劇增的情況下,根據當前業務情況及流量對一些服務和頁面有策略的降級,以此釋放伺服器資源以保證核心任務的正常執行 限流 限流的目的是通過對併發訪問 請求進行限速,或者對乙個時...
限流和限流演算法
目錄 一 什麼是限流 二 為什麼需要限流 三 那些場景需要用到限流 3.1 對外服務 3.2 對內服務 四 限流演算法 4.1 計數器演算法 4.2 漏桶演算法 4.3 令牌桶演算法 限流其實是指當系統資源不夠,不足以應對大量請求,即系統資源與訪問量出現矛盾的時候,我們為了保證有限的資源能夠正常服務...
php令牌桶演算法實現介面限流
前端每次請求從令牌桶取走令牌,後端勻速向桶內投遞令牌,如果前端取到令牌,則說明這次請求有效,否則讓前端再次請求或者等待。避免了大量請求下伺服器壓力過大導致的崩潰問題。令牌桶類 class token catch redi ception exception 令牌初始化 public function...