Java高併發系統的限流策略

2021-08-21 14:15:45 字數 2433 閱讀 5665

在大資料量高併發訪問時,經常會出現服務或介面面對暴漲的請求而不可用的情況,甚至引發連鎖反映導致整個系統崩潰。此時你需要使用的技術手段之一就是限流,當請求達到一定的併發數或速率,就進行等待、排隊、降級、拒絕服務等。

在開發高併發系統時有三把利器用來保護系統:快取、降級和限流。

快取比較好理解,在大型高併發系統中,如果沒有快取資料庫將分分鐘被爆,系統也會瞬間癱瘓。使用快取不單單能夠提公升系統訪問速度、提高併發訪問量,也是保護資料庫、保護系統的有效方式。大型**一般主要是「讀」,快取的使用很容易被想到。在大型「寫」系統中,快取也常常扮演者非常重要的角色。比如累積一些資料批量寫入,記憶體裡面的快取佇列(生產消費),以及hbase寫資料的機制等等也都是通過快取提公升系統的吞吐量或者實現系統的保護措施。甚至訊息中介軟體,你也可以認為是一種分布式的資料快取。

服務降級是當伺服器壓力劇增的情況下,根據當前業務情況及流量對一些服務和頁面有策略的降級,以此釋放伺服器資源以保證核心任務的正常執行。降級往往會指定不同的級別,面臨不同的異常等級執行不同的處理。根據服務方式:可以拒接服務,可以延遲服務,也有時候可以隨機服務。根據服務範圍:可以砍掉某個功能,也可以砍掉某些模組。總之服務降級需要根據不同的業務需求採用不同的降級策略。主要的目的就是服務雖然有損但是總比沒有好。

限流可以認為服務降級的一種,限流就是限制系統的輸入和輸出流量已達到保護系統的目的。一般來說系統的吞吐量是可以被測算的,為了保證系統的穩定執行,一旦達到的需要限制的閾值,就需要限制流量並採取一些措施以完成限制流量的目的。比如:延遲處理,拒絕處理,或者部分拒絕處理等等。

令牌桶(token bucket)、漏桶(leaky bucket)和計數器演算法是最常用的三種限流的演算法。

計數器限流演算法也是比較常用的,主要用來限制總併發數,比如資料庫連線池大小、執行緒池大小、程式訪問併發數等都是使用計數器演算法。也是最簡單粗暴的演算法。

使用計數器限流示例1:

public class countratelimiterdemo  else  catch (interruptedexception e)  finally }}

}

使用aomicinteger來進行統計當前正在併發執行的次數,如果超過域值就簡單粗暴的直接響應給使用者,說明系統繁忙,請稍後再試或其它跟業務相關的資訊。

弊端:使用 aomicinteger 簡單粗暴超過域值就拒絕請求,可能只是瞬時的請求量高,也會拒絕請求。

使用計數器限流示例2

public class countratelimiterdemo 

try catch (interruptedexception e) finally }}

使用semaphore訊號量來控制併發執行的次數,如果超過域值訊號量,則進入阻塞佇列中排隊等待獲取訊號量進行執行。如果阻塞佇列中排隊的請求過多超出系統處理能力,則可以在拒絕請求。

相對atomic優點:如果是瞬時的高併發,可以使請求在阻塞佇列中排隊,而不是馬上拒絕請求,從而達到乙個流量削峰的目的。

漏桶演算法即leaky bucket是一種非常常用的限流演算法,可以用來實現流量整形(traffic shaping)和流量控制(traffic policing)。貼了一張維基百科上示意圖幫助大家理解:

漏桶演算法的主要概念如下:

它的主要目的是控制資料注入到網路的速率,平滑網路上的突發流量,資料可以以任意速度流入到漏桶中。漏桶演算法提供了一種機制,通過它,突發流量可以被整形以便為網路提供乙個穩定的流量。 漏桶可以看作是乙個帶有常量服務時間的單伺服器佇列,如果漏桶為空,則不需要流出水滴,如果漏桶(包快取)溢位,那麼水滴會被溢位丟棄。

漏桶演算法比較好實現,在單機系統中可以使用佇列來實現(.net中tpl dataflow可以較好的處理類似的問題,你可以在這裡找到相關的介紹),在分布式環境中訊息中介軟體或者redis都是可選的方案。

令牌桶演算法的原理是系統會以乙個恆定的速度往桶裡放入令牌,而如果請求需要被處理,則需要先從桶裡獲取乙個令牌,當桶裡沒有令牌可取時,則拒絕服務。 當桶滿時,新新增的令牌被丟棄或拒絕。

令牌桶演算法是乙個存放固定容量令牌(token)的桶,按照固定速率往桶裡新增令牌。令牌桶演算法基本可以用下面的幾個概念來描述:

令牌演算法是根據放令牌的速率去控制輸出的速率,也就是上圖的to network的速率。to network我們可以理解為訊息的處理程式,執行某段業務或者呼叫某個rpc。

漏桶和令牌桶的比較

令牌桶可以在執行時控制和調整資料處理的速率,處理某時的突發流量。放令牌的頻率增加可以提公升整體資料處理的速度,而通過每次獲取令牌的個數增加或者放慢令牌的發放速度和降低整體資料處理速度。而漏桶不行,因為它的流出速率是固定的,程式處理速度也是固定的。

整體而言,令牌桶演算法更優,但是實現更為複雜一些。

高併發場景下的限流策略

目錄快取 降級 限流 漏桶演算法 令牌桶演算法 漏桶演算法與令牌桶演算法的區別 有效提公升熱點資料的訪問效率,在高併發 大流量的場景降低服務端壓力。當訪問量快速增長 服務可能會出現一些問題 響應超時 或者會存在非核心服務影響到核心流程的效能時,仍然需要保證服務的可用性,即便是有損服務。所以意味著我們...

高併發環境下的限流策略

在開發高併發系統時,有很多手段來防止系統過載 快取 降級 限流。快取的目的是提公升系統訪問速度和增大系統的吞吐量,降級和限流的目的如下 降級 降級是當服務出問題或者影響到核心流程的效能時需要暫時遮蔽掉某些功能,等高峰或者問題解決後再開啟。降級一般有幾種實現手段,自動降級和人工降級 1 通過配置降級開...

高併發系統設計 限流

前面學習過的熔斷和降級都是通過暫時關閉某些非核心服務或者元件來保護核心系統的可用性。但是並不是所有的場景下都可以使用熔斷降級的策略,例如當核心服務產生比較大的影響時,總不能把核心服務進行熔斷與降級,些時一般採用限流方案來進行保護。限流指的是通過限制到達系統的併發請求數量,保證系統能夠正常響應部分使用...