.NET中彈性和瞬時(shí)處理庫Polly的使用詳解
寫在前面
Polly 是一個(gè) .NET 彈性和瞬態(tài)故障處理庫,允許開發(fā)人員以 Fluent 和線程安全的方式來實(shí)現(xiàn)重試、斷路、超時(shí)、隔離和回退策略。
Polly 的七種策略介紹
重試(Retry): 當(dāng)出現(xiàn)故障時(shí)自動(dòng)進(jìn)行重試
斷路(Circuit-breaker):當(dāng)系統(tǒng)遇到嚴(yán)重問題時(shí),快速回饋失敗比讓用戶/調(diào)用者等待要好,限制系統(tǒng)出錯(cuò)的體量,有助于系統(tǒng)恢復(fù)。
超時(shí)(Timeout):當(dāng)系統(tǒng)超過一定時(shí)間的等待,我們就幾乎可以判斷不可能會(huì)有成功的結(jié)果,直接去干別的事情。
隔離(Bulkhead Isolation):當(dāng)系統(tǒng)的一處出現(xiàn)故障時(shí),可能促發(fā)多個(gè)失敗的調(diào)用,很容易耗盡主機(jī)的資源(如 CPU)。下游系統(tǒng)出現(xiàn)故障可能導(dǎo)致上游的故障的調(diào)用,甚至可能蔓延到導(dǎo)致系統(tǒng)崩潰。所以要將可控的操作限制在一個(gè)固定大小的資源池中,以隔離有潛在可能相互影響的操作。
回退(Fallback):有些錯(cuò)誤無法避免,就要有備用的方案。這個(gè)就像瀏覽器不支持一些新的 CSS 特性就要額外引用一個(gè) polyfill 一樣。一般情況,當(dāng)無法避免的錯(cuò)誤發(fā)生時(shí),我們要有一個(gè)合理的返回來代替失敗。
緩存(Cache):一般我們會(huì)把頻繁使用且不會(huì)怎么變化的資源緩存起來,以提高系統(tǒng)的響應(yīng)速度。如果不對(duì)緩存資源的調(diào)用進(jìn)行封裝,那么我們調(diào)用的時(shí)候就要先判斷緩存中有沒有這個(gè)資源,有的話就從緩存返回,否則就從資源存儲(chǔ)的地方(比如數(shù)據(jù)庫)獲取后緩存起來,再返回,而且有時(shí)還要考慮緩存過期和如何更新緩存的問題。Polly 提供了緩存策略的支持,使得問題變得簡(jiǎn)單。
策略包(Policy Wrap):一種操作會(huì)有多種不同的故障,而不同的故障處理需要不同的策略。這些不同的策略必須包在一起,作為一個(gè)策略包,才能應(yīng)用在同一種操作上。這就是文章開頭說的 Polly 的彈性,即各種不同的策略能夠靈活地組合起來。
通過NuGet安裝Polly類庫:
官方項(xiàng)目地址: https://github.com/App-vNext/Polly
代碼實(shí)現(xiàn)
/// <summary> /// FallBack => 當(dāng)出現(xiàn)故障,則進(jìn)入降級(jí)動(dòng)作 /// </summary> public static void Case1() { ISyncPolicy policy = Policy.Handle<ArgumentException>() .Fallback(() => { Console.WriteLine("Error occured"); }); policy.Execute(() => { Console.WriteLine("Job Start"); throw new ArgumentException("Hello Polly!"); Console.WriteLine("Job End"); }); } /// <summary> /// Retry => 重試 /// </summary> public static void Case2() { ISyncPolicy policy = Policy.Handle<Exception>().Retry(3); try { policy.Execute(() => { Console.WriteLine("Job Start"); if (DateTime.Now.Second % 10 != 0) { throw new Exception("Special error occured"); } Console.WriteLine("Job End"); }); } catch (Exception ex) { Console.WriteLine("There's one unhandled exception : " + ex.Message); } } /// <summary> /// CircuitBreaker => 短路保護(hù) /// </summary> public static void Case3() { // Stop for 10s after retry 6 times ISyncPolicy policy = Policy.Handle<Exception>() .CircuitBreaker(6, TimeSpan.FromSeconds(10)); while (true) { try { policy.Execute(() => { Console.WriteLine("Job Start"); throw new Exception("Special error occured"); Console.WriteLine("Job End"); }); } catch (Exception ex) { Console.WriteLine("There's one unhandled exception : " + ex.Message); } Thread.Sleep(500); } } /// <summary> /// Timeout 與 Wrap => Wrap是指策略封裝,可以把多個(gè)ISyncPolicy合并到一起執(zhí)行。Timeout則是指超時(shí)處理,但是超時(shí)策略一般不能直接使用,而是其其他策略封裝到一起使用。 /// </summary> public static void Case4() { try { ISyncPolicy policyException = Policy.Handle<TimeoutRejectedException>() .Fallback(() => { Console.WriteLine("Fallback"); }); ISyncPolicy policyTimeout = Policy.Timeout(3, Polly.Timeout.TimeoutStrategy.Pessimistic); ISyncPolicy mainPolicy = Policy.Wrap(policyTimeout, policyException); mainPolicy.Execute(() => { Console.WriteLine("Job Start..."); Thread.Sleep(5000); throw new Exception(); Console.WriteLine("Job End..."); }); } catch (Exception ex) { Console.WriteLine($"Unhandled exception : {ex.GetType()} : {ex.Message}"); } } /// <summary> /// 異步方法 /// </summary> public static async void Case5() { var policy = Policy<byte[]>.Handle<Exception>() .FallbackAsync(async c => { Console.WriteLine("Executed Error!"); return new byte[0]; }, async r => { Console.WriteLine(r.Exception); }); policy.WrapAsync(Policy.TimeoutAsync(5, TimeoutStrategy.Pessimistic, async (context, timespan, task) => { Console.WriteLine("Timeout!"); })); var bytes = await policy.ExecuteAsync(async () => { Console.WriteLine("Start Job"); HttpClient httpClient = new HttpClient(); var result = await httpClient.GetByteArrayAsync("https://img-blog.csdnimg.cn/img_convert/50f2b9069f40b88ea8348492d56abb87.png"); Console.WriteLine("Finish Job"); return result; }); Console.WriteLine($"Length of bytes : {bytes.Length}"); }
調(diào)用示例
Case1:
Case2:
Case3:
到此這篇關(guān)于.NET中彈性和瞬時(shí)處理庫Polly的使用詳解的文章就介紹到這了,更多相關(guān).NET Polly內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET?Core管理應(yīng)用程序狀態(tài)
這篇文章介紹了ASP.NET?Core管理應(yīng)用程序狀態(tài)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04Asp.net 后臺(tái)添加CSS、JS、Meta標(biāo)簽的方法
是從Asp.net 后臺(tái)添加CSS、JS、Meta標(biāo)簽的寫法,我們這里寫成函數(shù)方便以后使用,需要的朋友可以參考下2013-12-12asp.net下模態(tài)對(duì)話框關(guān)閉之后繼續(xù)執(zhí)行服務(wù)器端代碼的問題
asp.net下模態(tài)對(duì)話框關(guān)閉之后繼續(xù)執(zhí)行服務(wù)器端代碼的問題...2007-04-04sql server中批量插入與更新兩種解決方案分享(asp.net)
xml和表值函數(shù)的相對(duì)復(fù)雜些這里簡(jiǎn)單貼一下bcp和SqlDataAdapter進(jìn)行批量跟新插入方法,未經(jīng)整理還望見諒2012-05-05詳解Asp.net web.config customErrors 如何設(shè)置
這篇文章主要介紹了詳解Asp.net web.config customErrors 如何設(shè)置,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02