[分散式]對高併發流量控制的一點思考
前言
在實際專案中,曾經遭遇過線上5W+QPS的峰值,也在壓測狀態下經歷過10W+QPS的大流量請求,本篇部落格的話題主要就是自己對高併發流量控制的一點思考。
應對大流量的一些思路
首先,我們來說一下什麼是大流量?
大流量,我們很可能會冒出:TPS(每秒事務量),QPS(每秒請求量),1W+,5W+,10W+,100W+...。其實並沒有一個絕對的數字,如果這個量造成了系統的壓力,影響了系統的效能,那麼這個量就可以稱之為大流量了。
其次,應對大流量的一些常見手段是什麼?
快取:說白了,就是讓資料儘早進入快取,離程式近一點,不要大量頻繁的訪問DB。
降級:如果不是核心鏈路,那麼就把這個服務降級掉。打個比喻,現在的APP都講究千人千面,拿到資料後,做個性化排序展示,如果在大流量下,這個排序就可以降級掉!
限流:大家都知道,北京地鐵早高峰,地鐵站都會做一件事情,就是限流了!想法很直接,就是想在一定時間內把請求限制在一定範圍內,保證系統不被沖垮,同時儘可能提升系統的吞吐量。
注意到,有些時候,快取和降級是解決不了問題的,比如,電商的雙十一,使用者的購買,下單等行為,是涉及到大量寫操作,而且是核心鏈路,無法降級的,這個時候,限流就比較重要了。
那麼接下來,我們重點說一下,限流。
限流的常用方式
限流的常用處理手段有:計數器、滑動視窗、漏桶、令牌。
計數器
計數器是一種比較簡單的限流演算法,用途比較廣泛,在介面層面,很多地方使用這種方式限流。在一段時間內,進行計數,與閥值進行比較,到了時間臨界點,將計數器清0。
計數器思想
程式碼例項
計數器程式碼實現
這裡需要注意的是,存在一個時間臨界點的問題。舉個例子,在12:01:00到12:01:58這段時間內沒有使用者請求,然後在12:01:59這一瞬時發出100個請求,OK,然後在12:02:00這一瞬時又發出了100個請求。這裡你應該能感受到,在這個臨界點可能會承受惡意使用者的大量請求,甚至超出系統預期的承受。
滑動視窗
由於計數器存在臨界點缺陷,後來出現了滑動視窗演算法來解決。
滑動視窗原理圖
滑動視窗的意思是說把固定時間片,進行劃分,並且隨著時間的流逝,進行移動,這樣就巧妙的避開了計數器的臨界點問題。也就是說這些固定數量的可以移動的格子,將會進行計數判斷閥值,因此格子的數量影響著滑動視窗演算法的精度。
漏桶
雖然滑動視窗有效避免了時間臨界點的問題,但是依然有時間片的概念,而漏桶演算法在這方面比滑動視窗而言,更加先進。
有一個固定的桶,進水的速率是不確定的,但是出水的速率是恆定的,當水滿的時候是會溢位的。
漏桶演算法思想
程式碼實現
漏桶程式碼實現
令牌桶
注意到,漏桶的出水速度是恆定的,那麼意味著如果瞬時大流量的話,將有大部分請求被丟棄掉(也就是所謂的溢位)。為了解決這個問題,令牌桶進行了演算法改進。
令牌桶原理
生成令牌的速度是恆定的,而請求去拿令牌是沒有速度限制的。這意味,面對瞬時大流量,該演算法可以在短時間內請求拿到大量令牌,而且拿令牌的過程並不是消耗很大的事情。(有一點生產令牌,消費令牌的意味)
不論是對於令牌桶拿不到令牌被拒絕,還是漏桶的水滿了溢位,都是為了保證大部分流量的正常使用,而犧牲掉了少部分流量,這是合理的,如果因為極少部分流量需要保證的話,那麼就可能導致系統達到極限而掛掉,得不償失。
程式碼實現
令牌桶程式碼實現
限流神器:Guava RateLimiter
Guava不僅僅在集合、快取、非同步回撥等方面功能強大(可以參考博主的《使用Google Guava快樂程式設計》),而且還給我們封裝好了限流的API!
Guava RateLimiter基於令牌桶演算法,我們只需要告訴RateLimiter系統限制的QPS是多少,那麼RateLimiter將以這個速度往桶裡面放入令牌,然後請求的時候,通過tryAcquire()方法向RateLimiter獲取許可(令牌)。
程式碼示例
RateLimiter
分散式場景下的限流
上面所說的限流的一些方式,都是針對單機而言的,其實大部分的場景,單機的限流已經足夠了。分散式下限流的手段常常需要多種技術相結合,比如Nginx+Lua,Redis+Lua等去做。本文主要討論的是單機的限流,這裡就不在詳細介紹分散式場景下的限流了。
一句話,讓系統的流量,先到佇列中排隊、限流,不要讓流量直接打到系統上。
作者:張豐哲
連結:https://www.jianshu.com/p/d9504fc0af4d
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
相關文章
- [分散式][高併發]高併發架構分散式架構
- iOS 點贊功能高併發的思考iOS
- [分散式][高併發]熱點快取的架構優化分散式快取架構優化
- 【高併發】之分散式全域性唯一 ID分散式
- [分散式][高併發]限流的四種策略分散式
- 「分散式技術專題」併發系列一:基於加鎖的併發控制分散式
- 分散式鎖不是控制併發冪等的方式分散式
- 設計一個支援高併發的分散式鎖,商品維度分散式
- 面試集錦(八)分散式與高併發面試分散式
- 分散式流量控制框架sentinel初探分散式框架
- 高併發架構系列:分散式鎖的由來、特點及Redis分散式鎖的實現詳解架構分散式Redis
- [分散式]高併發案例---庫存超發問題分散式
- [分散式]架構設計原則--高併發分散式架構
- jmeter介面效能測試-高併發分散式部署JMeter分散式
- 【高併發】如何實現億級流量下的分散式限流?這些理論你必須掌握!!分散式
- 「分散式技術專題」併發系列二:基於時間的併發控制分散式
- 「分散式技術專題」併發系列三:樂觀併發控制之原型系統(分散式驗證)分散式原型
- [分散式][高併發]熔斷策略和最佳實踐分散式
- Jmeter效能測試:高併發分散式效能測試JMeter分散式
- 分散式叢集與多執行緒高併發分散式執行緒
- 【高併發】由InterruptedException異常引發的思考Exception
- 關於高併發和分散式中的冪等處理分散式
- 如何實現一個TCC分散式事務框架的一點思考分散式框架
- 取代ZooKeeper!高併發下的分散式一致性開源元件StateSynchronizer分散式元件
- 高併發和大流量解決方案
- 「分散式技術專題」併發系列三:樂觀併發控制之理論研究分散式
- PHP高併發和大流量的解決方案PHP
- 高併發核心技術 - 冪等性 與 分散式鎖分散式
- [分散式][高併發]負載均衡方案和演算法分散式負載演算法
- 高併發服務端分散式系統設計概要服務端分散式
- 關於Java併發多執行緒的一點思考Java執行緒
- 從零開始的高併發(二)--- Zookeeper實現分散式鎖分散式
- 分散式、高併發與多執行緒、你分辨的清嗎?分散式執行緒
- 【高併發】億級流量場景下如何實現分散式限流?看完我徹底懂了!!(文末有福利)分散式
- 「分散式技術專題」併發系列三:樂觀併發控制之原型系統分散式原型
- 我對人生的一點思考
- Java億級流量高併發設計方案Java
- 分散式鎖--高併發優化實踐(分段加鎖思想)!分散式優化