.NET中彈性和瞬時(shí)處理庫(kù)Polly的使用詳解
寫在前面
Polly 是一個(gè) .NET 彈性和瞬態(tài)故障處理庫(kù),允許開發(fā)人員以 Fluent 和線程安全的方式來(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í),快速回饋失敗比讓用戶/調(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í)候就要先判斷緩存中有沒有這個(gè)資源,有的話就從緩存返回,否則就從資源存儲(chǔ)的地方(比如數(shù)據(jù)庫(kù))獲取后緩存起來(lái),再返回,而且有時(shí)還要考慮緩存過(guò)期和如何更新緩存的問(wèn)題。Polly 提供了緩存策略的支持,使得問(wèn)題變得簡(jiǎn)單。
策略包(Policy Wrap):一種操作會(huì)有多種不同的故障,而不同的故障處理需要不同的策略。這些不同的策略必須包在一起,作為一個(gè)策略包,才能應(yīng)用在同一種操作上。這就是文章開頭說(shuō)的 Polly 的彈性,即各種不同的策略能夠靈活地組合起來(lái)。
通過(guò)NuGet安裝Polly類庫(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)文章
MVC使用Controller代替Filter完成登錄驗(yàn)證(Session校驗(yàn))學(xué)習(xí)筆記5
這篇文章主要介紹了MVC使用Controller代替Filter完成登錄驗(yàn)證即Session校驗(yàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Asp.net調(diào)試的一些問(wèn)題小結(jié)
這篇文章主要介紹了asp.net調(diào)試方便的知識(shí)點(diǎn),在CSDN找了一些相關(guān)的解決方法,不敢獨(dú)享,供大家相互學(xué)習(xí)交流之用2013-11-11
asp.net生成Excel并導(dǎo)出下載五種實(shí)現(xiàn)方法
有關(guān)Excel下載的文章網(wǎng)上想必有很多,利用閑暇時(shí)間整理了一些有Excel下載方法的文章,接下來(lái)介紹五種實(shí)現(xiàn)Excel下載的方法,感興趣的朋友可以了解下,或許對(duì)你學(xué)習(xí)Excel下載有所幫助2013-02-02
ASP.NET數(shù)據(jù)庫(kù)編程之處理文件訪問(wèn)許可
ASP.NET數(shù)據(jù)庫(kù)編程之處理文件訪問(wèn)許可...2006-09-09
ASP.NET State service狀態(tài)服務(wù)的問(wèn)題解決方法
每次重啟機(jī)器以后,在.NET2005上跑Web程序老是遇到這樣的問(wèn)題2008-11-11

