.Net彈性和瞬態(tài)故障處理庫(kù)Polly實(shí)現(xiàn)彈性策略
和故障處理策略不同的是,彈性策略并不是針對(duì)委托執(zhí)行過(guò)程中的異常進(jìn)行處理,而是改變委托本身的行為,因此彈性策略并沒(méi)有故障定義這一過(guò)程,它的處理流程為:
- 定義策略
- 應(yīng)用策略
Polly對(duì)彈性策略也做了不少支持,本文這里就簡(jiǎn)單的介紹一下。
彈性策略:超時(shí)(Timeout)
超時(shí)策略用于控制委托的運(yùn)行時(shí)間,如果達(dá)到指定時(shí)間還沒(méi)有運(yùn)行,則觸發(fā)超時(shí)異常。
Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Pessimistic);
超時(shí)策略常見(jiàn)的重載版本有如下幾個(gè):
Policy.Timeout(300); Policy.Timeout(TimeSpan.FromMilliseconds(3)); Policy.Timeout(() => TimeSpan.FromSeconds(3)); Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Optimistic);
超時(shí)策略:
Polly支持兩種超時(shí)策略:
- TimeoutStrategy.Pessimistic: 悲觀模式
當(dāng)委托到達(dá)指定時(shí)間沒(méi)有返回時(shí),不繼續(xù)等待委托完成,并拋超時(shí)TimeoutRejectedException異常。 - TimeoutStrategy.Optimistic:樂(lè)觀模式
這個(gè)模式依賴于 co-operative cancellation,只是觸發(fā)CancellationTokenSource.Cancel函數(shù),需要等待委托自行終止操作。
其中悲觀模式比較容易使用,因?yàn)樗恍枰谖蓄~外的操作,但由于它本身無(wú)法控制委托的運(yùn)行,函數(shù)本身并不知道自己被外圍策略取消了,也無(wú)法在超時(shí)的時(shí)候中斷后續(xù)行為。因此用起來(lái)反而還不是那么實(shí)用。
一個(gè)樂(lè)觀模式的的策略示例如下:
var policy = Policy.Timeout(300);
var cts = new CancellationTokenSource();
policy.Execute(ct =>
{
for (int i = 0; i < 1000; i++)
{
Thread.Sleep(100);
ct.ThrowIfCancellationRequested();
}
}, cts.Token);復(fù)合策略:
在日常的使用中,僅僅只有超時(shí)往往是并不夠的,很多時(shí)候還需要和重試等其它故障處理策略一起使用,如:
Policy.Handle<TimeoutRejectedException>()
.Retry(3)
.Wrap(Policy.Timeout(3, TimeoutStrategy.Pessimistic));彈性策略:無(wú)操作(NoOp)
在開(kāi)發(fā)過(guò)程中,處于測(cè)試或定位問(wèn)題時(shí)的需要,有時(shí)我們也需要一個(gè)沒(méi)有任何行為的策略,Polly系統(tǒng)默認(rèn)提供了一個(gè).
Policy.NoOp();
這個(gè)啥都沒(méi)干,也沒(méi)啥好介紹的了。
彈性策略:緩存(Cache)
有的時(shí)候,數(shù)據(jù)更新并不是頻繁的,此時(shí)可以使用緩存策略減少對(duì)服務(wù)的訪問(wèn),提高系統(tǒng)性能:
var memoryCacheProvider =
new Polly.Caching.MemoryCache.MemoryCacheProvider(new System.Runtime.Caching.MemoryCache("cache"));
var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5));
//Context.ExecutionKey就是cache的key
var context = new Context("cache_key");
for (int i = 0; i < 3; i++)
{
var cache = cachePolicy.Execute(_ =>
{
Console.WriteLine("get value");
return 3;
}, context);
Console.WriteLine(cache);
}PS:這個(gè)示例使用了MemoryCache,需要使用Nuget安裝Polly.Caching.MemoryCache程序包,以及添加System.Runtime.Caching的引用。
從運(yùn)行結(jié)果可以看到,雖然三次執(zhí)行都有結(jié)果,但系統(tǒng)只有第一次才需要執(zhí)行函數(shù),剩下兩次都是直接從緩存中獲取的結(jié)果。
系統(tǒng)也提供了多種不同的過(guò)期策略:
Policy.Cache(memoryCacheProvider, new AbsoluteTtl(DateTimeOffset.Now.Date.AddDays(1))); Policy.Cache(memoryCacheProvider, new SlidingTtl(TimeSpan.FromMinutes(5)));
對(duì)于布式緩存,Polly也有默認(rèn)的實(shí)現(xiàn),只需要安裝Polly.Caching.IdistributedCache程序包即可,它提供了SqlServer和Redis的支持。
關(guān)于Cache的更多內(nèi)容,可以參考官方文檔:Cache
彈性策略:艙壁隔離(Bulkhead Isolation)
艙壁隔離是一種并發(fā)控制的行為,并發(fā)控制是一個(gè)比較常見(jiàn)的模式,Polly也提供了這方面的支持,如:
//該策略下最多只有12個(gè)任務(wù)并發(fā)執(zhí)行 Policy.Bulkhead(12);
超過(guò)了并發(fā)數(shù)的任務(wù)會(huì)拋BulkheadRejectedException,如果要放在隊(duì)列中等待,Polly也提供了等待隊(duì)列的支持:
Policy.Bulkhead(12, 100);
這種方式下,有12個(gè)并發(fā)任務(wù),每個(gè)任務(wù)維持著一個(gè)并發(fā)隊(duì)列,每個(gè)隊(duì)列可以自持最大100個(gè)任務(wù)。
不過(guò),和微軟自己的DataFlow模塊比起來(lái),感覺(jué)Polly模塊的并發(fā)控制的功能還是比較弱的。不過(guò)這也它本身的應(yīng)用場(chǎng)景也相關(guān),如果需要更強(qiáng)大的策略,也可以自行封裝。
彈性策略:策略封裝(PolicyWrap)
我們可以通過(guò)PolicyWrap的方式,封裝出一個(gè)更加強(qiáng)大的策略:
var fallback = Policy<int>.Handle<TimeoutException>().Fallback(100); var retry = Policy<int>.Handle<TimeoutException>().Retry(2); Policy.Wrap(fallback, retry);
這個(gè)策略就是將Retry和Fallback組合起來(lái),形成一個(gè)retry and fallback的策略,也可以寫(xiě)成如下形式:
var retryAndFallback = fallback.Wrap(retry);
當(dāng)執(zhí)行這個(gè)新策略時(shí):
retryAndFallback.Execute(DoSomething);
等價(jià)于執(zhí)行:
fallback.Execute(()=> retry.Execute(DoSomething));
到此這篇關(guān)于Polly實(shí)現(xiàn)彈性策略的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
ASP.NET?MVC實(shí)現(xiàn)多選下拉框保存并顯示
這篇文章介紹了ASP.NET?MVC實(shí)現(xiàn)多選下拉框保存并顯示的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
ASP.NET Core通用主機(jī)實(shí)現(xiàn)托管服務(wù)
這篇文章介紹了ASP.NET Core通用主機(jī)實(shí)現(xiàn)托管服務(wù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07
ASP.NET MVC下的四種驗(yàn)證編程方式[續(xù)篇]
ASP.NET MVC支持四種服務(wù)端驗(yàn)證的編程方式(“手工驗(yàn)證”、“標(biāo)注ValidationAttribute特性”、“讓數(shù)據(jù)類(lèi)型實(shí)現(xiàn)IValidatableObject或者IDataErrorInfo”),那么在ASP.NET MVC框架內(nèi)部是如何提供針對(duì)這四種不同編程方式的支持的呢?本篇文章就來(lái)聊聊這背后的故事。2016-12-12
vs2012創(chuàng)建的ado.net模型無(wú)法實(shí)例化的解決方案
本文給大家分享的是升級(jí)vs2012后,發(fā)現(xiàn)創(chuàng)建數(shù)據(jù)模型無(wú)法實(shí)例化使用,嘗試了很多種方法,最后在度娘的幫助下,才解決了這個(gè)問(wèn)題,這里記錄下來(lái),分享給大家。2015-03-03
ASP.NET Core自定義中間件如何讀取Request.Body與Response.Body的內(nèi)容詳解
這篇文章主要給大家介紹了關(guān)于在ASP.NET Core自定義中間件中如何讀取Request.Body與Response.Body的內(nèi)容,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用ASP.NET Core具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
.net搜索查詢并實(shí)現(xiàn)分頁(yè)實(shí)例
.net搜索查詢并實(shí)現(xiàn)分頁(yè)實(shí)例,需要的朋友可以參考一下2013-03-03
.Net Core實(shí)現(xiàn)圖片文件上傳下載功能
這篇文章主要為大家詳細(xì)介紹了.Net Core實(shí)現(xiàn)圖片文件上傳下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
asp.net與excel互操作實(shí)現(xiàn)代碼
將datatable中的數(shù)據(jù)導(dǎo)出到指定的excel文件中2010-04-04
如何使用.NET Core 選項(xiàng)模式【Options】
這篇文章主要介紹了如何使用.NET Core 選項(xiàng)模式,文中講解非常詳細(xì),代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07

