3.限流模式
服務的容量和效能是有限的,在第3章中會介紹如何在架構設計過程中評估服務的最大效能和容量,然而,即使我們在設計階段考慮到了效能壓力的問題,並從設計和部署上解決了這些問題,但是業務量是隨著時間的推移而增長的,突然上量對於乙個飛速發展的平台來說是很常見的事情。
針對服務突然上量,我們必須有限流機制,限流機制一般會控制訪問的併發量,例如每秒允許處理的併發使用者數及查詢量、請求量等。
有如下幾種主流的方法實現限流。
1)計數器
通過原子變數計算單位時間內的訪問次數,如果超出某個閾值,則拒絕後續的請求,等到下乙個單位時間再重新計數。
在計數器的實現方法中通常定義了乙個迴圈陣列(見下圖),例如:定義5個元素的環形陣列,計數週期為1s,可以記錄4s內的訪問量,其中有1個元素為當前時間點的標誌,通常來說每秒程式都會將前面3s的訪問量列印到日誌,供統計分析。
我們將時間的秒數除以陣列元素的個數5,然後取模,對映到環形陣列裡的資料元素,假如當前時間是1 000 000 002s,那麼對應當前時間的環形陣列裡的第3個元素,下標為2。
此時的陣列元素的資料如下圖所示。
在上圖中,當前時間為1 000 000 002s,對應的計數器在第3個元素,下標為2,當前請求是在這個時間週期內的第1個訪問請求,程式首先需要對後乙個元素即第4個元素,也就是下標為3的元素清零;在1 000 000 002s內,任何乙個請求如果發現下標為3的元素不為0,則都會將原子變數3清零,並記錄清零的時間。
這時程式可以對第3個元素即下標為2的元素,進行累加並判斷是否達到閾值,如果達到閾值,則拒絕請求,否則請求通過;同時,列印本次及之前3秒的資料訪問量,列印結果如下。
當前:1次,前1s:302次,前2s:201次,前3s:518次
然而,如果當前秒一直沒有請求量,下一秒的計數器始終不能清零,則下一秒的請求到達後要首先清零再使用,並更新清零時間。
在下一秒的請求到達後,若檢查到當前秒對應的原子變數計數器不為0,而且最後的清零時間不是上一秒,則先對當前秒的計數器清零,再進行累加操作,這避免發生上一秒無請求的場景,或者上一秒的請求由於執行緒排程延遲而沒有清零下一秒的場景,後面這種場景發生的概率較小。
另外一種實現計數器的簡單方法是單獨啟動乙個執行緒,每隔一定的時間間隔執行對下一秒的原子變數計數器清零操作,這個時間間隔必須小於計數時間間隔。
2)令牌筒
令牌筒是乙個流行的實現限流的技術方案,它通過乙個執行緒在單位時間內生產固定數量的令牌,然後把令牌放入佇列,每次請求呼叫需要從桶中拿取乙個令牌,拿到令牌後才有資格執行請求呼叫,否則只能等待拿到令牌再執行,或者直接丟棄。
令牌筒的結構如下圖所示。
3)訊號量
限流類似於生活中的漏洞,無論倒入多少油,下面有漏管的流量是有限的,實際上我們在應用層使用的訊號量也可以實現限流。
4.失效轉移模式
若微服務架構中發生了熔斷和限流,則該如何處理被拒絕的請求呢?解決這個問題的模式叫作失效轉移模式,通常分為下面幾種。
**部落格:
軟體體系架構閱讀筆記十四
在服務化系統或者微服務架構中,我們如何拆分服務才是最合理的?服務拆分到什麼樣的粒度最合適?按照微服務的初衷,服務要按照業務的功能進行拆分,直到每個服務的功能和職責單一,甚至不可再拆分為止,以至於每個服務都能獨立部署,擴容和縮容方便,能夠有效地提高利用率。拆得越細,服務的耦合度越小,內聚性越好,越適合...
軟體體系架構閱讀筆記九
微服務不需要像普通服務那樣成為一種獨立的功能或者獨立的資源。定義中稱,微服務是需要與業務能力相匹配,這種說法完全正確。不幸的是,仍然意味著,如果能力模型粒度的設計是錯誤的,那麼,我們就必須付出很多代價。如果你閱讀了fowler的整篇文章,你會發現,其中的指導建議是非常實用的。在決定將所有元件組合到一...
軟體架構閱讀筆記01
進行軟體架構的學習,先粗略的讀一遍 大型 架構 了解軟體架構。大致明白了幾點,首先利用軟體架構 解決問題,解決業務問題,進行優化,然而架構不能夠解決所有問題。其次,軟體架構只有親身經歷從低到高才能夠了解架構,我只能夠粗略理解,沒有實際進行,不能深入解讀。軟體架構主要講的內容之一就是 分類。也就是軟體...