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

Code綜藝圈發表於2021-04-19

前言

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

  • 網路不通,突然又好了;
  • 伺服器當機了;
  • 呼叫服務介面超時了;
  • 呼叫介面報錯啦;
  • 通訊資訊傳送失敗需要重發;

以上只是列舉了一些常遇到的問題,對於一些小專案可能簡單的處理一下就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)剩下的功能進行分享~~~

一個被程式搞醜的帥小夥,關注"Code綜藝圈",跟我一起學~~~

圖片

相關文章