大話常用限流演算法與應用場景

2021-10-11 00:26:43 字數 3551 閱讀 7627

公司產品老大讓做乙個搶金幣的活動,規定乙個使用者5秒內最多搶10個金幣

初級工程師小j(junior)同學拿到這個需求後立馬就開幹,直接用userid為key在redis中儲存,來乙個請求就讓計數器自增一下再拿到自增後的結果,判斷結果值是否超過了規定的閥值,再來個將key設為5秒過期

小a然後快速寫出**:

/**

* 限制為5秒10次

*/private long rangeseconds = 5l;

private integer maxrate = 10;

/*** 優點:編碼簡單

* 缺點:邊界值統計不準確

*/public object setnxlimit(long userid)

return increment;

}

小j開發好後這個需求他開始膨脹了,心想著:沒錯,我就是個人才,分分鐘搞定了這個需求

測試大佬大t對小a發布後的**進行了測試,初步測試發現確實實現了乙個使用者5秒內最多只能有10個請求可以成功的要求。但是測試大佬大t在測試時發現對於如果每秒持續傳送請求,會造成一直提示限流的情況,統計在邊界點有並不準確

因為小j的功能統計不準確,大t向小j打回了bug,說他這個功能有問題,統計不準確。於是身為人才的小a與測試測試大佬大t吵起來了

此時小j的研發小組長大h過來了,分析了下原因,是因為計數器演算法限流對於最後一次請求時會一直對key進行續期導致的。為了快速搞定這個功能,大h讓中級工程師小n(normal)來協助下小j來實現限流這個需求

公司產品老大讓做乙個搶金幣的活動,規定乙個使用者5秒內最多搶3個金幣

小n決定用時間視窗來解決這個問題。每次統計時以5秒為單位統計當前時間前5秒的請求是否超過限制

小n然後快速寫出**:

/**

* 滑動視窗

* 優點:統計精準,可以解決邊界值

* 缺點:如果限制範圍長,則資料量可能會比較大

*/public object windowlimit(long userid)

return count;

}

小n開發好後這個需求他開始膨脹了,心想著:沒錯,我就是個人才,分分鐘搞定了這個小a搞不定的需求

測試大佬大t對小n發布後的**進行了測試,發現確實實現了產品所提的需求

因為小n的功能統計準確,然後大t同意了小n的**進行上線

大n心想著:看來姜還是老的辣呀,小n是個人才

在小n的**上線到伺服器後,運維大佬大g通過監控發現redis的記憶體占用隨著使用者量的增加暴增了許多,這時大g慌了,心想著:這可不行,redis記憶體使用增長太快了,萬一redis崩了他的地位可不保了呀,趕緊向研發小組長大h求助尋求支援吧

研發小組長大h看了下小n提交的**,一下就發現了問題的所在。因為滑動視窗演算法用到了zset實現的,它會將使用者的每次請求都記錄到zset中,這樣就會導致redis記憶體占用過高

為了快速解決滑動視窗限流演算法占用記憶體過多的問題,大h決定將派出高階軟體工程師小s(senior)來協助小n解決解決上面的需求

公司產品老大讓做乙個搶金幣的活動,規定乙個使用者5秒內最多搶10個金幣

為了解決滑動視窗限流演算法占用過多儲存空間的問題,小s決定採用令牌桶限流演算法來解決這個問題

小s在腦海中將令牌桶演算法的思路回憶了一下:假設每個請求想要訪問某個資源,在訪問前必須先拿到乙個門票(token)才能進入訪問,token的產生是按照一定的速度恆定產生的,token產生後放在乙個桶內,順便給這個桶取個名字就叫它令牌桶。當令牌桶內的令牌充足時,才能向請求者下發令牌,令牌桶內令牌不足時則進行限流。如果某段時間內桶內的令牌數太多,則令牌則會溢位。令牌桶限流演算法因為只需要很少的幾個變數便可實現,相比於滑動視窗限流演算法來講漏斗演算法更加節約記憶體空間

小s然後快速寫出**:

/**

* 令牌桶

*/ public object tokenbucketlimit(long userid) else else

}return null;

}

小s開發好後這個需求他開始膨脹了,心想著:沒錯,我就是個人才,分分鐘搞定了這個小n搞不定的需求

測試大佬大t對小s發布後的**進行了測試,發現確實實現了產品所提的需求

因為小s的功能統計準確,然後大t同意了小s的**進行上線

上線後運維大佬大g通過觀察系統監控,觀察redis的記憶體使用情況發現小s的**比之前小n時提交的**更加節約了記憶體

大n心想著:這tm究竟修改了個啥?我tm還真沒有測出來,感覺結果沒得啥變化呀。不管了,總之小n和小s都是人才

大g心想著:看來真是強中更有強中手,小s是個人才

在小s的**上線到伺服器後,運維大佬大g通過監控發現雖然redis的記憶體佔用量低了,但某段時間內的伺服器cpu資源占用很高,這時大g又慌了,心想著:這可不行,cpu使用率不穩定,萬一伺服器崩了他的地位還是保不住呀,趕緊再次向研發小組長大h求助尋求支援吧

公司產品老大讓做乙個搶金幣的活動,規定乙個使用者5秒內最多搶10個金幣,並保證請求穩定,不允許有突發請求

為了實現請求限流並保證請求平穩,研發小組長大h決定親自出馬了

大h決定採用漏斗限流演算法來解決限流時不允許有突發的需求

其解決思路大致辭是這樣的:根據漏斗流水的結構來進行模擬,通過維護漏斗容量、漏斗流水速度、當前漏斗內水總量這幾個變數來進行限流控制。因為漏斗的出水率的速度是恆定的,則可以確保伺服器的請求平穩

大h然後快速寫出**:

/**

* 漏斗演算法限流

*/ public object funnellimit(long userid) else else }}

大h開發好後這個需求他仍然淡定著

測試大佬大n對大h發布後的**進行了測試,發現確實實現了產品所提的需求

因為大h的功能統計準確,然後大n同意了大h的**進行上線

上線後運維大佬大g通過觀察系統監控,發現在使用者量很多時cpu資源也達到平穩了

測試大佬大n心想著:這tm究竟又修改了個啥?實不相瞞我tm還真沒有測出來,感覺結果仍然沒得啥變化呀。不管了,總之小n和小s和大h都是人才

運維大佬大g心想著:研發小組長大h並非浪得虛名呀,大h才真的是個人才

限流演算法的選擇就像談戀愛,不同的限流演算法對應著不同的妹子各有特點,至於究竟最後要和哪個妹子談戀愛,需要在深入了解了各自的特點後再進行選擇

總之還是那句話,沒有最好的,只有最合適的(具體要用哪種限流演算法得要看具體的專案和應用場景)

常用限流演算法與應用場景

限流是在微服務介面時,面對高併發場景必須考慮的問題。現在限流演算法主要有以下幾種 其中令牌桶演算法變種還可以分為 單速率三色標記演算法 雙速率三色標記演算法 計數器法是限流演算法裡最簡單也是最容易實現的一種演算法。一般是限制一段時間能夠通過的請求數,比如某個介面規定5秒鐘的訪問次數不能超過10次,那...

Hash演算法應用場景

一.雜湊演算法的定義 1.雜湊演算法又叫雜湊演算法,是將任意長度的二進位制值對映為較短的固定長度的二進位制值,這個小的二進位制值稱為雜湊值。它的原理其實很簡單,就是把一段交易資訊轉換成乙個固定長度的字串。2.雜湊表是基於快速訪問的角度設計的,是一種典型的空間換時間的做法,二.從set map談到ha...

演算法 常用經典動態規劃應用場景總結

1 給定乙個矩陣m,從左上角開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有數字累加起來就是路徑和,返回所有路徑中最小路徑和,如果給定的m如大家看到的樣子,路徑1,3,1,0,6,1,0就是路徑中和最小的,所以返回12。矩陣m13 5981 3450 6188 40解題思路 生成大小和m...