前言
對於運行中的系統,可以說百分百的小夥伴會經常遇見以下問題:
網絡不通,突然又好了;
服務器宕機了;
調用服務接口超時了;
調用接口報錯啦;
通訊信息發送失敗需要重發;
以上只是列舉了一些常遇到的問題,對於一些小項目可能簡單的處理一下就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源創計劃”,歡迎正在閱讀的你也加入,一起分享。