一、引言
在高並發系統中,經常需要限制系統中的電流化妝。一方面是防止大量的請求使服務器過載,導致服務不可用,另一方面是防止網絡攻擊。
常用的限流方法,如hystrix、應用線程池隔離、超過線程池的負載和go融合邏輯。一般來說,應用服務器(如Tomcat容器)通過限制線程數量來控制並發性,而流量也由時間窗口的平均速度來控制。常見的限流緯度包括IP、URI和用戶訪問頻率的限流。
_當前的限制通常在網關層完成,如nginx、openresty、kong、zuul、spring cloud gateway等,也可以通過aop在應用層完成。
2。限流算法
1。計數器算法
_計數器算法利用計數器來實現限流是有點簡單和粗糙的,一般我們會限制一秒鍾內可以傳遞的請求數,比如限流qps是100,算法的思想是從第一個請求開始計時,在下一個1s中,每個請求的計數都會增加1,如果累積ve數達到100,隨后的請求將完成。部門拒絕了。1s后,將計數恢復為0並重新開始計數。具體實現如下:對於每個服務調用,可以添加計數器1和Atomiclong incrementandget()方法返回的最新值,並將最新值與閾值進行比較。這種實現方式,我相信大家都知道有一個缺點:如果我在一個單位時間的前10毫秒內通過了100個請求,那么后面的990毫秒只能眼睜睜地拒絕請求。我們稱這種現象為“尖峰現象”。
2。漏桶算法
為了消除“尖峰現象”,可以采用漏桶算法來實現電流限制。漏桶算法的名字非常生動。算法中有一個容器,類似於日常生活中使用的漏斗。當請求進入時,相當於水倒入漏斗,然后從下小口緩慢均勻地流出。無論上面的流量有多大,下面的流量保持不變。無論服務調用者多么不穩定,都會使用泄漏桶算法來限制電流,並每隔10毫秒處理一次請求。因為處理速度是固定的,所以傳入請求的速度是未知的。可能有許多請求突然出現。無法處理的請求首先放在存儲桶中。因為它是一個桶,所以必須有一個容量上限。如果存儲桶滿了,新的請求將被丟棄。
_在算法的實現中,可以准備一個隊列來保存請求,可以使用線程池(調度執行器服務)來定期從隊列中獲取請求並執行它們,從而一次獲得多個並發執行。
該算法在使用后也有不足之處:不能處理短突發流量。
三。令牌桶算法
從某種意義上說,令牌桶算法是對漏桶算法的改進。bucket算法可以限制請求調用的速率,而token bucket算法可以限制平均調用速率,同時允許一定程度的突發調用。在令牌存儲桶算法中,有一個存儲固定數量令牌的存儲桶。算法中有一種機制,可以以一定的速率將令牌放入存儲桶中。每個請求調用都需要首先獲取令牌。只有獲得令牌后,才能繼續執行。否則,選擇是等待可用的令牌或直接拒絕。玩代幣是一個連續的動作。如果桶中的令牌數達到上限,則將丟棄這些令牌。所以這種情況存在。桶中有大量可用的令牌。此時,可以通過令牌直接執行傳入請求。例如,將qps設置為100,然后在當前限制器初始化后一秒鍾,桶中有100個令牌。此時,服務還不可用。啟動完成后,限流器能承受100個瞬時請求。因此,請求只在bucket中沒有令牌時等待,這相當於以一定的速率執行。
_實現思想:您可以准備一個隊列來保存令牌,並通過線程池定期將令牌生成到隊列中。每個請求,您都可以從隊列中獲取一個令牌並繼續執行。
三。Spring Cloud網關電流限制
在SpringCloudGateway中,有過濾器,所以上面提到的三個過濾器可以自己實現i