當前位置:網站首頁>阿裏四面一問:說說之前公司系統都用過的哪些限流模式?
阿裏四面一問:說說之前公司系統都用過的哪些限流模式?
2022-05-14 22:36:22【Java愛好狂】
一、限流思路
常見的系統服務限流模式有:熔斷、服務降級、延遲處理和特殊處理四種。
1、熔斷
將熔斷措施嵌入到系統設計中,當系統出現問題時,若短時間內無法修複,系統會自動開啟熔斷開關,拒絕流量訪問,避免大流量對後端的過載請求。
除此之外,系統還能够動態監測後端程序的修複情况,當程序已恢複穩定時,就關閉熔斷開關,恢複正常服務。
常見的熔斷組件有 Hystrix 以及阿裏的 Sentinel。
在Spring Cloud框架裏,熔斷機制通過Hystrix實現。Hystrix會監控微服務間調用的狀况,當失敗的調用到一定閾值,缺省是5秒內20次調用失敗,就會啟動熔斷機制。
熔斷機制的注解是@HystrixCommand,Hystrix會找有這個注解的方法,並將這類方法關聯到和熔斷器連在一起的代理上。
2、服務降級
將系統的所有功能服務進行一個分級,當系統出現問題需要緊急限流時,可將不是那麼重要的功能進行降級處理,停止服務,保障核心功能正常運作。
例如在電商平臺中,如果突發流量激增,可臨時將商品評論、積分等非核心功能進行降級,停止這些服務,釋放出機器和 CPU 等資源來保障用戶正常下單。
這些降級的功能服務可以等整個系統恢複正常後,再來啟動,進行補單/補償處理。
除了功能降級以外,還可以采用不直接操作數據庫,而全部讀緩存、寫緩存的方式作為臨時降級方案。
熔斷&降級
- 相同點:目標一致 都是從可用性和可靠性出發,為了防止系統崩潰;用戶體驗類似,最終都讓用戶體驗到的是某些功能暫時不可用。
- 不同點:觸發原因不同,服務熔斷一般是某個服務(下遊服務,即被調用的服務)故障引起;
- 而服務降級一般是從整體負荷考慮。
3、延遲處理
延遲處理需要在系統的前端設置一個流量緩沖池,將所有的請求全部緩沖進這個池子,不立即處理。後端真正的業務處理程序從這個池子中取出請求依次處理,常見的可以用隊列模式來實現。
這就相當於用异步的方式去减少了後端的處理壓力,但是當流量較大時,後端的處理能力有限,緩沖池裏的請求可能處理不及時,會有一定程度延遲。
4、特權處理
這個模式需要將用戶進行分類,通過預設的分類,讓系統優先處理需要高保障的用戶群體,其它用戶群的請求就會延遲處理或者直接不處理。
二、限流算法
常見的限流算法有三類:計數器算法、漏桶算法和令牌桶算法。
1、計數器算法
計數器算法是限流算法中最簡單最容易的一種,如上圖每分鐘只允許100個請求,第一個請求進去的時間為startTime,在startTime + 60s內只允許100個請求 。
當60s內超過十個請求後,則拒絕請求;不超過的允許請求,到第60s 重新設置時間。
View Code
利用計數器算法比如要求某一個接口,1分鐘內的請求不能超過100次。
可以在開始時設置一個計數器,每次請求,該計數器+1;如果該計數器的值大於10並且與第一次請求的時間間隔在1分鐘內,那麼說明請求過多則限制請求直接返回或不處理,反之。
如果該請求與第一次請求的時間間隔大於1分鐘,並且該計數器的值還在限流範圍內,那麼重置該計數器。
計算器算法雖然簡單,但它有一個很致命的臨界問題。
上圖可以看出假若有一個惡意用戶,他在0:59時,瞬間發送了100個請求,並且在1:00時,又瞬間發送了100個請求,那麼其實這個用戶在 1秒後,瞬間發送了200個請求。
而上述計數器算法規定的是1分鐘最多100個請求,也就是每秒鐘最多1.7個請求,而用戶通過在時間窗口的重置節點處突發請求,可以瞬間超過限流的速率限制,這個漏洞可能會瞬間壓垮服務應用。
上述漏洞問題其實是因為計數器限流算法統計的精度太低,可以借助滑動窗口算法將臨界問題的影響降低。
2、滑動窗口
上圖中,整個紅色的矩形框錶示一個時間窗口。在計數器算法限流的例子中,一個時間窗口就是一分鐘。在這裏將時間窗口進行劃分,比如圖中,將滑動窗口劃成了6格,每格代錶的是10秒鐘。每過10秒鐘,時間窗口就會往右滑動一格。每一個格子都有自己獨立的計數器counter,比如當一個請求在0:35秒的時候到達,那麼0:30~0:39對應的counter就會加1。
那麼滑動窗口是怎麼解决剛才的臨界問題的呢?
上圖,0:59到達的100個請求會落在灰色的格子中,而1:00到達的請求會落在橘黃色的格子中。當時間到達1:00時,窗口會往右移動一格,那麼此時時間窗口內的總請求數量一共是200個,超過了限定的100個,所以此時能够檢測出來觸發了限流。
經過比較發現發現,計數器算法其實就是滑動窗口算法。只是它沒有對時間窗口做進一步地劃分,所以只有1格。所以,當滑動窗口的格子劃分得越多,則滑動窗口的滾動就越平滑,限流的統計就會越精確。
3、漏桶算法
漏桶算法思路很簡單,水(請求)先進入到漏桶裏,漏桶以一定的速度出水,當水流入速度過大會超過桶可接納的容量時直接溢出,可以看出漏桶算法能强行限制數據的傳輸速率。
使用漏桶算法,可以保證接口會以一個常速速率來處理請求,所以漏桶算法必定不會出現臨界問題。
漏洞算法實現類:
View Code
使用漏桶限流:
View Code
漏洞算法的兩個優點:
- 削峰:有大量流量進入時,會發生溢出,從而限流保護服務可用。
- 緩沖:不至於直接請求到服務器,緩沖壓力,消費速度固定,因為計算性能固定。
4、令牌桶算法
令牌桶算法思想:以固定速率產生令牌,放入令牌桶,每次用戶請求都得申請令牌,令牌不足則拒絕請求或等待。
上圖,令牌桶算法會以一個恒定的速度往桶裏放入令牌,而如果請求需要被處理,則需要先從桶裏獲取一個令牌,當桶裏沒有令牌可取時,則拒絕服務。
View Code
令牌桶算法默認從桶裏移除令牌是不需要耗費時間的,如果給移除令牌設置一個延時時間,那麼實際上又采用了漏桶算法的思路。
至於臨界問題的場景,在0:59秒的時候,由於桶內積滿了100個token,所以這100個請求可以瞬間通過。但是由於token是以較低的速率填充的,所以在1:00的時候,桶內的token數量不可能達到100個,那麼此時不可能再有100個請求通過。所以令牌桶算法可以很好地解决臨界問題。
漏桶與令牌桶算法的區別
- 主要區別在於“令牌桶算法”能够强行限制數據的傳輸速率,而“令牌桶算法”在能够限制數據的平均傳輸速率外,還允許某種程度的突發傳輸。
- 在“令牌桶算法”中,只要令牌桶中存在令牌,那麼就允許突發地傳輸數據直到達到用戶配置的門限,因此它適合於具有突發特性的流量。
- 令牌桶算法由於實現簡單,且允許某些流量的突發,對用戶友好,所以被業界采用地較多。
- 具體情况具體分析,只有最合適的算法,沒有最優的算法。
基於穀歌RateLimiter實現限流
Google開源工具包Guava提供了限流工具類RateLimiter,該類基於令牌桶算法(Token Bucket)來完成限流,非常易於使用。RateLimiter經常用於限制對一些物理資源或者邏輯資源的訪問速率,它支持兩種獲取permits接口,一種是如果拿不到立刻返回false(tryAcquire()),另一種會阻塞等待一段時間看能不能拿到(tryAcquire(long timeout, TimeUnit unit))。
View Code
三、集群限流
前面幾種算法都屬於單機限流的範疇,但簡單的單機限流仍無法滿足複雜的場景。比如為了限制某個資源被每個用戶或者商戶的訪問次數,5s只能訪問2次,或者一天只能調用1000次,這種場景單機限流是無法實現的,這時就需要通過集群限流進行實現。
可以使用Redis實現集群限流,大概思路是每次有相關操作的時候,就向redis服務器發送一個incr命令。
redisOperations.opsForValue().increment()
比如需要限制某個用戶訪問某個詳情/details接口的次數,只需要拼接用戶id和接口名,加上當前服務名的前綴作為redis的key,每次該用戶訪問此接口時,只需要對這個key執行incr命令,再這個key帶上過期時間,就可以實現指定時間的訪問頻率。
原文鏈接:https://www.cnblogs.com/taojietaoge/p/15744243.html
版權聲明
本文為[Java愛好狂]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/134/202205141820531153.html
邊欄推薦
猜你喜歡
隨機推薦
- VMware虛擬機 之 NAT模式詳解
- 【Devops】kubernetes網絡
- 新式茶飲“拿捏”年輕人,“八馬茶業”們的出路在哪?
- 機器學習之金融風控
- 1.67版本vscode括號著色(Bracket Pair Colorizer)取消
- MySQL日期查詢使用的方法函數
- HugeGraph客戶端APP開發(一)
- [.Net]使用Soa庫+Abp搭建微服務項目框架(五):服務發現和健康監測
- 添加虛擬內存,不添加硬盤的方式
- Redis源碼學習(25),雙端鏈錶學習,adlist.h
- 虛幻5新特性之EnhancedInput
- 緩存命中錶示什麼?
- sencha touch 在線實戰培訓 第一期 第四節
- “我們從 Google 離職了”
- yolov5訓練測試與源碼解讀
- 原生JS 實現輪播圖效果
- 邏輯回歸 解决報錯:ValueError: Solver lbfgs supports only ‘l2‘ or ‘none‘ penalties, got l1 penalty.
- Oracle OCI 計算、存儲、網絡工具旨在降低雲複雜性
- Go項目實戰之日志必備篇[開源十年項目第11次更新]
- Shell脚本變量和運算符
- 聊聊找工作
- 是能力更是文化,談談IT系統的安全發布
- tensorflow學習筆記(五)
- vitest支持cjs的workaround(TypeScript產物commonjs場景)
- 並發編程系列之Lock鎖可重入性與公平性
- 淺談 Fiori Fundamentals 和 SAP UI5 Web Components 的關系
- RAM/FIFO學習回顧
- 最新版2022年任我行管家婆工貿版ERP M7 V22.0進銷存財務生產管理軟件網絡版——雲上的集團化制造管理系統
- 【機器學習05】LASSO回歸與ElasticNet(彈性網)
- Idea快捷鍵
- 關於創建模態窗口和非模態窗口的研究
- An End-to-End Steel Surface Defect Detection Approach via Fusing Multiple Hierarchical Features-閱讀筆記
- 【性能測試】第五篇 | Jmeter環境安裝
- Matplotlib使用指南,100個案例從入門到進階!(附源代碼)
- Dots + interval stats and geoms
- SIGIR2022 | 基於用戶價格偏好及興趣偏好的會話推薦
- Cloudreve自建雲盤實站:容量和速度自己來决定
- 利用騰訊雲函數搭建免費代理池
- Redis的安裝及基本數據類型
- js輪播圖效果,透明度漸變實現