天天看點

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後

前言

高并發,幾乎是每個程式員都想擁有的經驗。原因很簡單:随着流量變大,會遇到各種各樣的技術問題,比如接口響應逾時、CPU load升高、GC頻繁、死鎖、大資料量存儲等等,這些問題能推動我們在技術深度上不斷精進。

我們知道,高并發代表着大流量,高并發系統設計的魅力就在于我們能夠憑借自己的聰明才智設計巧妙的方案,進而抵抗巨大流量的沖擊,帶給使用者更好的使用體驗。這些方案好似能操縱流量,讓流量更加平穩得被系統中的服務群組件處理。

造成雪崩的真實場景

1.4.1 服務提供者不可用

  • 硬體故障:

    如網絡故障、硬碟損壞等。
  • 程式的 bug:

    如算法需要占用大量 CPU 的計算時間導緻 CPU 使用率過高。
  • 緩存擊穿:

    比如應用剛重新開機,短時間内緩存是失效的,導緻大量請求直接通路到了資料庫,資料庫不堪重負,服務不可用。
  • 秒殺和大促:

    服務短時間承載不了那麼多請求量。

1.4.2 重試加大流量

  • 使用者連續重試:

    比如使用者看到界面上沒有響應,是以又操作了一遍,結果又增加了一倍請求量。
  • 程式重試機制:

    比如代碼中有多次重試的邏輯,一次失敗後,過幾秒後再重試,重試個三次就取消重試,走異常處理分支了。也是增加了請求量。

五、如何防止雪崩

方案

出問題前預防:限流、主動降級、隔離

出問題後修複:熔斷、被動降級

「本篇主要來講解熔斷機制。」 後續幾篇會講解其他方案。

六、熔斷原理和算法

1.6.1 熔斷概念

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後

熔斷這個概念來源于電路系統中的

保險絲

熔斷。當電流過大時,保險絲熔斷,防止因

電流過大

損壞電器元器件,或因電流過大,導緻元器件熱度過高,發生火災。

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後

「實體公式」 電功率 P = I^2 * R,I 代表電流,元器件的電阻 R 不變的情況下,電流越大,電功率約大,電阻做的電功大部分都用來

發熱

了,是以電功率越大,發熱越嚴重。(還好高中實體沒忘。)

放到我們系統中,怎麼了解熔斷?

如果在某段時間内,調用某個服務非常慢甚至逾時,就可以将這個服務熔斷,後續其他服務再調用這個服務就直接傳回,告訴其他服務:「“已經熔斷了,你别調用我了,過段時間再來試下吧。”」

1.6.2 如何熔斷

「熔斷有個原則」 一段時間内,統計失敗的次數或者失敗請求的占比超過一定門檻值,就進行熔斷。

詳細的原理如下圖所示:

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後

1.6.3 統計請求的算法

  • 請求通路到背景服務後,首先判斷熔斷開關是否打開。
  • 如果熔斷開關

    已打開

    ,則表明目前請求不能被處理。
  • 如果熔斷開關

    未打開

    ,則判斷時間視窗是否已滿。
  • 如果時間視窗

    未滿

    ,則請求桶中的請求數加 1。
  • 如果傳回的響應有異常,則失敗桶的

    失敗數加 1

    ,如果傳回的響應沒有異常,則成功桶的

    成功數加 1

  • 如果時間視窗

    已滿

    ,則開始判斷是否需要熔斷。

1.6.4 熔斷的恢複算法

  • 當熔斷後,開關切換到

    斷開狀态

  • 過一段時間後,開關切換為

    半斷開狀态

    (Half-Open)。半斷開狀态下,允許對應用程式的一定數量的請求可以去調用服務,如果調用成功,則認為服務可以正常通路了,于是将開關切換為

    閉合狀态

  • 如果半斷開狀态下,還是有調用失敗的情況,則認為服務還沒有恢複,開關從半斷開狀态切換到

    斷開狀态

1.6.5 統計失敗率的時間視窗

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後
  • 時間視窗可以比喻為人坐在窗戶邊,看外面來往的車輛,一定時間内從窗戶外經過的車輛。

  • 每次請求,都會判斷時間視窗是否已滿(如5分鐘),如果時間視窗已滿,則重新開始計時,且清理請求數/成功數/失敗數。
  • 注意:第一次開始的起始時間預設為目前時間。

1.6.6 嘗試恢複服務的時間視窗

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後
  • 開關為斷開的狀态,經過一定時間後,比如 1 分鐘,設定為

    半斷開

    的狀态,嘗試發送請求檢測服務是否恢複。
  • 如果已恢複,則切換狀态為關閉狀态。如果未恢複,則切換狀态為

    斷開

    的狀态,經過 1 分鐘後,重複上面的步驟。
  • 這裡的時間視窗可以根據環境的運作狀态進行動态調整,比如第一次是 1 分鐘,第二次是 3 分鐘,第三次是 10 分鐘。

七、熔斷中間件

肯定有人會問了,你這上面講的原理,難道還真的自己去寫這套算法?

「答案:是的,項目中我們自己造了一個輪子:熔斷器。」

但這裡我不推薦大家這麼做。市面上還有更優秀的開源元件供大家使用,比如阿裡系的 

Sentinel

(推薦),Netflix 的 

Hystrix

(已停止更新)。

當然 Sentinel 就不在這篇講了,後續奉上~

寫在最後

可能有人會問我為什麼願意去花時間幫助大家實作求職夢想,因為我一直堅信時間是可以複制的。我犧牲了自己的大概十個小時寫了這片文章,換來的是成千上萬的求職者節約幾天甚至幾周時間浪費在無用的資源上。

OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後
OMG,學它!Spring容器如何解決循環依賴的原理前言寫在最後
上面的這些(算法與資料結構)+(Java多線程學習手冊)+(計算機網絡頂級教程)等學習資源我都在這裡公開分享出來

以上我的經曆希望能夠給大家帶來幫助,需要這些資料的朋友可以戳這裡,就可以免費拿到了

)+(計算機網絡頂級教程)等學習資源我都在這裡公開分享出來

以上我的經曆希望能夠給大家帶來幫助,需要這些資料的朋友可以戳這裡,就可以免費拿到了