.NET中彈性和瞬時(shí)處理庫(kù)Polly的使用詳解
寫(xiě)在前面
Polly 是一個(gè) .NET 彈性和瞬態(tài)故障處理庫(kù),允許開(kāi)發(fā)人員以 Fluent 和線(xiàn)程安全的方式來(lái)實(shí)現(xiàn)重試、斷路、超時(shí)、隔離和回退策略。
Polly 的七種策略介紹
重試(Retry): 當(dāng)出現(xiàn)故障時(shí)自動(dòng)進(jìn)行重試
斷路(Circuit-breaker):當(dāng)系統(tǒng)遇到嚴(yán)重問(wèn)題時(shí),快速回饋失敗比讓用戶(hù)/調(diào)用者等待要好,限制系統(tǒng)出錯(cuò)的體量,有助于系統(tǒng)恢復(fù)。
超時(shí)(Timeout):當(dāng)系統(tǒng)超過(guò)一定時(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ò)誤無(wú)法避免,就要有備用的方案。這個(gè)就像瀏覽器不支持一些新的 CSS 特性就要額外引用一個(gè) polyfill 一樣。一般情況,當(dāng)無(wú)法避免的錯(cuò)誤發(fā)生時(shí),我們要有一個(gè)合理的返回來(lái)代替失敗。
緩存(Cache):一般我們會(huì)把頻繁使用且不會(huì)怎么變化的資源緩存起來(lái),以提高系統(tǒng)的響應(yīng)速度。如果不對(duì)緩存資源的調(diào)用進(jìn)行封裝,那么我們調(diào)用的時(shí)候就要先判斷緩存中有沒(méi)有這個(gè)資源,有的話(huà)就從緩存返回,否則就從資源存儲(chǔ)的地方(比如數(shù)據(jù)庫(kù))獲取后緩存起來(lái),再返回,而且有時(shí)還要考慮緩存過(guò)期和如何更新緩存的問(wèn)題。Polly 提供了緩存策略的支持,使得問(wèn)題變得簡(jiǎn)單。
策略包(Policy Wrap):一種操作會(huì)有多種不同的故障,而不同的故障處理需要不同的策略。這些不同的策略必須包在一起,作為一個(gè)策略包,才能應(yīng)用在同一種操作上。這就是文章開(kāi)頭說(shuō)的 Polly 的彈性,即各種不同的策略能夠靈活地組合起來(lái)。
通過(guò)NuGet安裝Polly類(lèi)庫(kù):
官方項(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í)處理庫(kù)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)的方法,文中通過(guò)示例代碼介紹的非常詳細(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)簽的寫(xiě)法,我們這里寫(xiě)成函數(shù)方便以后使用,需要的朋友可以參考下2013-12-12asp.net下模態(tài)對(duì)話(huà)框關(guān)閉之后繼續(xù)執(zhí)行服務(wù)器端代碼的問(wèn)題
asp.net下模態(tài)對(duì)話(huà)框關(guān)閉之后繼續(xù)執(zhí)行服務(wù)器端代碼的問(wèn)題...2007-04-04.NET 中Worker Service的使用入門(mén)
隨著 .NET Core 3.0 的發(fā)布,ASP.NET 團(tuán)隊(duì)引入了一個(gè)新的 Worker Service 項(xiàng)目模板,該模板作為 .NET SDK 的一部分發(fā)布。在本文中,我將向您介紹這個(gè)新模板,以及使用它開(kāi)發(fā)的一些實(shí)際的服務(wù)示例。2021-05-05sql server中批量插入與更新兩種解決方案分享(asp.net)
xml和表值函數(shù)的相對(duì)復(fù)雜些這里簡(jiǎn)單貼一下bcp和SqlDataAdapter進(jìn)行批量跟新插入方法,未經(jīng)整理還望見(jiàn)諒2012-05-05詳解Asp.net web.config customErrors 如何設(shè)置
這篇文章主要介紹了詳解Asp.net web.config customErrors 如何設(shè)置,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02ASP.NET中常用的用來(lái)輸出JS腳本的類(lèi)
在ASP.NET中我們經(jīng)常需要輸出一些JS腳本,比如彈出一個(gè)警告窗口,返回到歷史頁(yè)面等JS功能,我看到網(wǎng)上好多這方面的代碼,以下代碼是其中之一。2010-02-02.net6?使用Senparc開(kāi)發(fā)小程序配置過(guò)程
這篇文章主要介紹了.net6?使用Senparc開(kāi)發(fā)小程序配置,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07