.Net彈性和瞬態(tài)故障處理庫Polly實現(xiàn)彈性策略
和故障處理策略不同的是,彈性策略并不是針對委托執(zhí)行過程中的異常進行處理,而是改變委托本身的行為,因此彈性策略并沒有故障定義這一過程,它的處理流程為:
- 定義策略
- 應用策略
Polly對彈性策略也做了不少支持,本文這里就簡單的介紹一下。
彈性策略:超時(Timeout)
超時策略用于控制委托的運行時間,如果達到指定時間還沒有運行,則觸發(fā)超時異常。
Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Pessimistic);
超時策略常見的重載版本有如下幾個:
Policy.Timeout(300); Policy.Timeout(TimeSpan.FromMilliseconds(3)); Policy.Timeout(() => TimeSpan.FromSeconds(3)); Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Optimistic);
超時策略:
Polly支持兩種超時策略:
- TimeoutStrategy.Pessimistic: 悲觀模式
當委托到達指定時間沒有返回時,不繼續(xù)等待委托完成,并拋超時TimeoutRejectedException異常。 - TimeoutStrategy.Optimistic:樂觀模式
這個模式依賴于 co-operative cancellation,只是觸發(fā)CancellationTokenSource.Cancel函數(shù),需要等待委托自行終止操作。
其中悲觀模式比較容易使用,因為它不需要在委托額外的操作,但由于它本身無法控制委托的運行,函數(shù)本身并不知道自己被外圍策略取消了,也無法在超時的時候中斷后續(xù)行為。因此用起來反而還不是那么實用。
一個樂觀模式的的策略示例如下:
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);
復合策略:
在日常的使用中,僅僅只有超時往往是并不夠的,很多時候還需要和重試等其它故障處理策略一起使用,如:
Policy.Handle<TimeoutRejectedException>() .Retry(3) .Wrap(Policy.Timeout(3, TimeoutStrategy.Pessimistic));
彈性策略:無操作(NoOp)
在開發(fā)過程中,處于測試或定位問題時的需要,有時我們也需要一個沒有任何行為的策略,Polly系統(tǒng)默認提供了一個.
Policy.NoOp();
這個啥都沒干,也沒啥好介紹的了。
彈性策略:緩存(Cache)
有的時候,數(shù)據(jù)更新并不是頻繁的,此時可以使用緩存策略減少對服務的訪問,提高系統(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:這個示例使用了MemoryCache,需要使用Nuget安裝Polly.Caching.MemoryCache程序包,以及添加System.Runtime.Caching的引用。
從運行結(jié)果可以看到,雖然三次執(zhí)行都有結(jié)果,但系統(tǒng)只有第一次才需要執(zhí)行函數(shù),剩下兩次都是直接從緩存中獲取的結(jié)果。
系統(tǒng)也提供了多種不同的過期策略:
Policy.Cache(memoryCacheProvider, new AbsoluteTtl(DateTimeOffset.Now.Date.AddDays(1))); Policy.Cache(memoryCacheProvider, new SlidingTtl(TimeSpan.FromMinutes(5)));
對于布式緩存,Polly也有默認的實現(xiàn),只需要安裝Polly.Caching.IdistributedCache程序包即可,它提供了SqlServer和Redis的支持。
關于Cache的更多內(nèi)容,可以參考官方文檔:Cache
彈性策略:艙壁隔離(Bulkhead Isolation)
艙壁隔離是一種并發(fā)控制的行為,并發(fā)控制是一個比較常見的模式,Polly也提供了這方面的支持,如:
//該策略下最多只有12個任務并發(fā)執(zhí)行 Policy.Bulkhead(12);
超過了并發(fā)數(shù)的任務會拋BulkheadRejectedException,如果要放在隊列中等待,Polly也提供了等待隊列的支持:
Policy.Bulkhead(12, 100);
這種方式下,有12個并發(fā)任務,每個任務維持著一個并發(fā)隊列,每個隊列可以自持最大100個任務。
不過,和微軟自己的DataFlow模塊比起來,感覺Polly模塊的并發(fā)控制的功能還是比較弱的。不過這也它本身的應用場景也相關,如果需要更強大的策略,也可以自行封裝。
彈性策略:策略封裝(PolicyWrap)
我們可以通過PolicyWrap的方式,封裝出一個更加強大的策略:
var fallback = Policy<int>.Handle<TimeoutException>().Fallback(100); var retry = Policy<int>.Handle<TimeoutException>().Retry(2); Policy.Wrap(fallback, retry);
這個策略就是將Retry和Fallback組合起來,形成一個retry and fallback的策略,也可以寫成如下形式:
var retryAndFallback = fallback.Wrap(retry);
當執(zhí)行這個新策略時:
retryAndFallback.Execute(DoSomething);
等價于執(zhí)行:
fallback.Execute(()=> retry.Execute(DoSomething));
到此這篇關于Polly實現(xiàn)彈性策略的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Asp.Net Core利用xUnit進行主機級別的網(wǎng)絡集成測試詳解
這篇文章主要給大家介紹了關于Asp.Net Core利用xUnit進行主機級別的網(wǎng)絡集成測試的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們來一起看看吧2018-12-12aspx實現(xiàn)的 jquery ui 的 flexgrid demo
這幾天沒事研究著jquery,真是個好東西,慢慢的知道了有jquery ui,一開始就被華麗的界面和簡單的操作給吸引了,尤其是里面的flexgrid,對我而言可以說是非常寶貴的東西2009-12-12Asp.net?core?使用SignalR推送消息過程詳解
ASP.NET?Core?SignalR?是一個開放源代碼庫,可用于簡化向應用添加實時?Web?功能。?實時?Web?功能使服務器端代碼能夠?qū)?nèi)容推送到客戶端,本文重點給大家介紹Asp.net?core?使用SignalR推送消息,感興趣的朋友一起看看吧2022-03-03asp.net DataTable相關操作集錦(篩選,取前N條數(shù)據(jù),去重復行,獲取指定列數(shù)據(jù)等)
這篇文章主要介紹了asp.net DataTable相關操作,包括篩選,取前N條數(shù)據(jù),去重復行,獲取指定列數(shù)據(jù)等.基本涵蓋了DataTable的常見操作技巧,需要的朋友可以參考下2016-06-06ASP.NET中控件的EnableViewState屬性及徹底禁用
如果我們在開發(fā)Web應用程序時,某些控件是不需要接受用戶的操作或只需要接受一次操作的時候,我們可以將這些控件的EnableViewState屬性改為false,這樣可以優(yōu)化我們的程序,提高網(wǎng)絡訪問的速度。2016-06-06