Polly-故障處理和彈性應對很有一手

前言

對於運行中的系統,可以說百分百的小夥伴會經常遇見以下問題:

  • 網絡不通,突然又好了;

  • 服務器宕機了;

  • 調用服務接口超時了;

  • 調用接口報錯啦;

  • 通訊信息發送失敗需要重發;

以上只是列舉了一些常遇到的問題,對於一些小項目可能簡單的處理一下就OK了(比如重啓或是重新發布),而對於微服務架構的項目,可能因爲一個服務掛掉、或是一臺服務器宕機、又或是網絡出現波動等情況,都可能會導致業務流程失敗,甚至會導致整個系統崩掉。所以對於系統瞬時故障需及時做出應對策略,對於可能會發生的故障需提前預防(彈性應變);Polly這個庫針對以上等情況進行封裝,通過策略的方式,靈活處理相關場景。

正文

1. 簡介

Polly是一種.NET彈性和瞬態故障處理庫,可以通過不同策略處理和應對故障場景,主要分爲兩大類:被動策略和主動策略,各自包含如下功能:

1.1 被動策略

主要針對故障的處理,避免如下:

  • 重試(Retry):在實際應用場景中往往有些失敗只是瞬時的,經過短暫的延時就可恢復,這種情況就可以採用重試策略;

  • 熔斷(Circuit Breaker):比如在調用接口發生異常時,當多次都返回異常,建議先熔斷一段時間,即不再處理業務接口,直接報錯;待熔斷時間過了之後可以重新處理請求,即快速響應失敗比讓用戶一直等待要合理;

  • 回退(Fallback):如果失敗之後怎麼處理?即在發生故障的時候找一個替代邏輯進行處理, 比如返回指定的結果或是進行下一步操作;

1.2 主動策略

主要是進行彈性擴展,而不是針對故障處理,關鍵點是改變原有業務邏輯的執行行爲,比如原業務邏輯超時了,就會執行指定的超時處理行爲;

  • 超時(Timeout ):確保調用者永遠不需要等待超過配置的超時時間,不然就會觸發超時異常;主要就是爲了提升用戶體驗;

  • 艙壁隔離(Bulkhead Isolation):即一個服務的故障不應該影響到整個系統(隔離);通過控制資源消耗,避免一個故障導致級聯服務也故障,最終影響整個系統;目的就是進行併發控制(限流),避免故障帶來的大範圍影響。

  • 緩存(Cache):將數據存入緩存中,後續的響應可以從緩存中獲取; 目的就是爲了提升性能;

  • 策略包裝( PolicyWrap):策略可以組合進行使用;目的就是爲了方便各種策略組合進行業務故障處理;

大概理解Polly功能之後,接下來就通過Demo的形式進一步瞭解各策略的使用;

2. 功能Demo演示

Polly使用步驟很簡單,兩個步驟完事:

  • 定義策略;

  • 執行策略;

以下的各功能的演示,主要體現的是用法,不會所有情況都舉例演示,僅提供思路;其中說明主要結合代碼,以註釋爲主:

2.1 重試(Retry)

代碼實現:

運行結果(測試的時候,用Release模式或者直接執行編譯後的執行文件,不然Debug模式的時候遇見異常會提示,查看結果不方便):

上面邏輯是失敗就重試,其實在實際應用場景,通常有一個時間間隔重試,每次重試遞增的時間不一樣,代碼如下:

運行結果如下:

2.2 熔斷(Circuit Breaker)

代碼實現:

運行結果:

上面這種只是常規熔斷方式,Polly還提供高級熔斷配置,根據熔斷比率進行熔斷,更加符合應用場景,通過設置樣本收集時間,然後計算收集的業務處理結果比率,如果達到熔斷比率就進行熔斷。代碼如下:

運行效果如下:

2.3 回退(Fallback)

代碼實現如下:

運行結果:

當異常發生的時候,也可以指定對應的操作邏輯。

2.4 超時(Timeout )

代碼實現:

運行結果:

超時這分爲樂觀超時(Optimistic timeout)和悲觀超時(Pessimistic timeout),樂觀超時需要CancellationToken 在業務邏輯中進行取消,而悲觀超時沒有取消的話,超時了還會繼續執行,上面的案例就顯示了,當觸發超時之後,業務邏輯等待一段時間之後,還會返回結果,這個過程是需要耗費相關性能的;根據需要可以自行選擇。樂觀超時就不演示了,和正常線程邏輯一樣,通過CancellationToken取消即可。

超時策略的最終目的就是考慮到用戶體驗,及時給用戶反饋,不讓用戶一直處於等待中~~~~

2.5 艙壁隔離(Bulkhead Isolation)

代碼實現:

運行效果:

其實在設置策略參數的時候,還可以指定等待隊列的數,也就是說當業務執行數達到設置併發數時,還可以繼續執行業務,只是這些業務先會進入等待隊列中;這裏就不詳細演示了,後續在API中在具體說明,對於限流這塊,放在API那塊可能更容易理解,這裏就先進了解。

2.6 緩存(Cache)

緩存這塊演示的是基於內存的,需要額外引入包Polly.Caching.Memory和Microsoft.Extensions.Caching.Memory,關於MemoryCache的具體細節,可以參考這篇文章(因MemoryCache鬧了個笑話)。

代碼實現:

運行效果:

關於緩存這塊,也是可以集成Redis進行做分佈式緩存的。後面的項目分享的時候再詳細說,如果小夥伴好奇,可以參照官網,用法和上面一樣,只是引用的包不一樣而已。

2.7 策略包裝( PolicyWrap)

代碼及運行效果:目的就是爲了組合策略,應對業務邏輯的各種情況。

上述只是演示了常用的策略使用方式,並沒有面面俱到,更加詳細內容可以參照官網,結合我的演示思路,看官網例子就很容易啦:

官網地址:https://github.com/App-vNext/Polly/wiki/PolicyWrap

總結

關於Polly,就先說到這,後面的Demo或項目中肯定還會用到的,在這裏用控制檯項目的方式演示,一方面是爲了方便,針對某個點好測試,另一方面是爲了說明Polly不是針對WebAPI調用採用的,而是根據需要在項目其他任何地方都可以用(好多小夥伴都認爲只是用於HttpClient調用API);

Polly瞭解大概情況之後,下期繼續接着網關(Ocelot)剩下的功能進行分享~~~


本文分享自微信公衆號 - 一線碼農聊技術(dotnetfly)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章