常見的限流算法及其原理剖析

1 何謂限流

限流,顧名思義,便是限制流量的意思。系統規定在一段時間內只能進入這麼多的流量,如果超過限額的話,那就不好意思了,我這個系統接受不了。通過限流算法,我們可以控制系統的 qps,更好地對系統提供保護。

本文致力於介紹幾種我們常用的限流算法,同時會對其原理進行一定程度的剖析,希望大家能有所收穫。

2 計數器算法

算法原理

計數器算法是最簡單的限流算法,假設我們規定 A 接口在1小時之內的訪問次數不能超過1000次,我們可以在開始時設置一個計數器,只有有一個請求進來,計數器的值就加一。如果計數器的值大於1000,而且該次請求與第一次請求的間隔時間小於1小時,說明請求過多,需要執行拒絕策略;如果該次請求與第一次請求的間隔時間大於1小時,直接重置計數器即可。

存在的問題

該算法雖然比較簡單,但是存在一個臨界問題。

假設存在一個惡意用戶,在第一個小時的最後一秒發送了1000個請求,又在第二個小時的第一秒再次發送了1000個請求,通過在時間窗口的重置節點處突發請求,瞬間超過我們的速率限制。惡意用戶可能通過這個算法的漏洞,在一個較短的時間內製造大量的流量,來壓垮我們的應用。

實現方法

使用 redis 的 incr 原子自增性。

3 滑動窗口算法

算法原理

計數器算法由於其存在的臨界問題,統計的精度過低,可能在時間窗口的重置節點處接收大量流量,爲解決這個問題,我們引入了滑動窗口算法。

我們依然使用上面的例子,把一個時間窗口設置爲1小時,然後我們再對時間窗口進行劃分。例如,我們把時間窗口劃分爲60格,即每一分鐘代表一格,每過一分鐘,時間窗口都會往右滑動一格,每一格都有自己的計數器。

對臨界問題的解決

我們上面探討過這個一個情節,一個惡意用戶在第一個小時的最後一秒發送了1000個請求,又在第二個小時的第一秒再次發送了1000個請求。在滑動窗口算法中,最後一秒到達的1000個請求會在一個格子中,第一秒到達的1000的請求會在一個格子中,當新的一分鐘到來時,時間窗口會向右移動一格,時間窗口的總請求數量一定超標(因爲時間窗口包括了最近的這兩個格子,這時至少有2000個請求),所以觸發限流操作。

計數器算法其實就是隻有一格的滑動窗口算法,當滑動窗口算法的格子劃分越多,限流的統計就越精確。

4 令牌桶算法

請求在被處理之前,需要首先獲取一個令牌,才能執行接下來的業務邏輯,處理完業務邏輯需要將令牌刪除。令牌桶是一個存放令牌的地方,它會根據限流大小,會按照一定的速率向桶中添加令牌。

令牌桶會設置最大的放置令牌限制,當令牌桶滿了,新添加的令牌會被直接丟棄;令牌桶也有最低限額,當令牌數到達最低限額時,請求處理完之後將不會刪除令牌。

在這裏插入圖片描述

5 漏桶算法

所謂漏桶,顧名思義,便是一個漏水的桶,我們往這個桶加水的速率可能是任意的,但桶漏水的速度是必然恆定的。如果流入水的速率過快,已經超過桶的容量大小,那水便會直接流出(被丟棄)。漏桶算法便是在此基礎上設計的。

所謂漏桶算法,便是當訪問請求到達時,直接放置進入漏桶,如漏桶當前容量已到達限流上限,則觸發限流策略。漏桶會以固定的速率釋放訪問請求,直到漏桶爲空。

6 聊聊令牌桶算法與漏桶算法的區別

漏桶算法可以限制數據的平均傳輸速率,而令牌桶算法除了能夠限制數據的平均傳輸速率外,還能夠允許某種程度的突發傳輸。因爲在令牌桶算法中,只要令牌桶中存在令牌,那麼就允許突發地傳輸數據直到達到用戶配置的門限,所以它適合於具有突發特性的流量。

參考:三種常見的限流算法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章