網站首頁 編程語言 正文
和故障處理策略不同的是,彈性策略并不是針對委托執行過程中的異常進行處理,而是改變委托本身的行為,因此彈性策略并沒有故障定義這一過程,它的處理流程為:
- 定義策略
- 應用策略
Polly對彈性策略也做了不少支持,本文這里就簡單的介紹一下。
彈性策略:超時(Timeout)
超時策略用于控制委托的運行時間,如果達到指定時間還沒有運行,則觸發超時異常。
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: 悲觀模式
當委托到達指定時間沒有返回時,不繼續等待委托完成,并拋超時TimeoutRejectedException異常。 - TimeoutStrategy.Optimistic:樂觀模式
這個模式依賴于?co-operative cancellation,只是觸發CancellationTokenSource.Cancel函數,需要等待委托自行終止操作。
其中悲觀模式比較容易使用,因為它不需要在委托額外的操作,但由于它本身無法控制委托的運行,函數本身并不知道自己被外圍策略取消了,也無法在超時的時候中斷后續行為。因此用起來反而還不是那么實用。
一個樂觀模式的的策略示例如下:
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)
在開發過程中,處于測試或定位問題時的需要,有時我們也需要一個沒有任何行為的策略,Polly系統默認提供了一個.
Policy.NoOp();
這個啥都沒干,也沒啥好介紹的了。
彈性策略:緩存(Cache)
有的時候,數據更新并不是頻繁的,此時可以使用緩存策略減少對服務的訪問,提高系統性能:
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的引用。
從運行結果可以看到,雖然三次執行都有結果,但系統只有第一次才需要執行函數,剩下兩次都是直接從緩存中獲取的結果。
系統也提供了多種不同的過期策略:
Policy.Cache(memoryCacheProvider, new AbsoluteTtl(DateTimeOffset.Now.Date.AddDays(1)));
Policy.Cache(memoryCacheProvider, new SlidingTtl(TimeSpan.FromMinutes(5)));
對于布式緩存,Polly也有默認的實現,只需要安裝Polly.Caching.IdistributedCache程序包即可,它提供了SqlServer和Redis的支持。
關于Cache的更多內容,可以參考官方文檔:Cache
彈性策略:艙壁隔離(Bulkhead Isolation)
艙壁隔離是一種并發控制的行為,并發控制是一個比較常見的模式,Polly也提供了這方面的支持,如:
//該策略下最多只有12個任務并發執行
Policy.Bulkhead(12);
超過了并發數的任務會拋BulkheadRejectedException,如果要放在隊列中等待,Polly也提供了等待隊列的支持:
Policy.Bulkhead(12, 100);
這種方式下,有12個并發任務,每個任務維持著一個并發隊列,每個隊列可以自持最大100個任務。
不過,和微軟自己的DataFlow模塊比起來,感覺Polly模塊的并發控制的功能還是比較弱的。不過這也它本身的應用場景也相關,如果需要更強大的策略,也可以自行封裝。
彈性策略:策略封裝(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);
當執行這個新策略時:
retryAndFallback.Execute(DoSomething);
等價于執行:
fallback.Execute(()=> retry.Execute(DoSomething));
原文鏈接:https://www.cnblogs.com/TianFang/p/8215732.html
相關推薦
- 2022-08-02 C#中的一些延時函數_C#教程
- 2022-04-28 WPF使用StackPanel棧面板布局_實用技巧
- 2023-05-05 Golang實現簡易的命令行功能_Golang
- 2022-04-14 Python?eval()函數和ast.literal_eval()的區別你知道嗎_python
- 2022-09-04 Python運行出現DeprecationWarning的問題及解決_python
- 2022-11-14 Windows進程的創建與結束
- 2022-12-10 Flutter改變狀態變量是否必須寫在setState回調詳解_Android
- 2022-01-19 【webpack5】webpack-dev-server 熱更新不能自動刷新瀏覽器
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支