使用 Polly 實現復雜策略(超時重試)


一、背景

第一次接觸 Polly 還是在做某個微服務系統的時候,那時只會使用單一的超時策略與重試策略,更加高級的特性就沒有再進行學習了。最近開為某個客戶開發 PC 端的上位機的時候,客戶有個需求,在發起請求之后如果 5 秒鍾沒有響應則進行重試,總共可以重試 3 次,如果 3 次請求都未返回數據,就視為請求失敗。

關於 Polly 的高級用法可以參考官方的 Wiki 文檔即可,國內也有很多優秀的介紹文章,例如 這篇這篇

二、思路

查閱了 Polly 的官方文檔之后,發現 Polly 提供了策略組合功能,每個 Policy 實例都可以調用其 Wrap() 方法與另外一個策略進行組合。

或者是通過 Policy 靜態類提供的 Warp() 靜態方法來指定需要組合的兩個策略。

根據需求描述來看,我們需要用到超時策略和重試策略,只要將其組合即可。不過這里需要注意一個坑,即他們的組合順序。

正確的組合順序應該是 **重試策略.Warp(超時策略) **,而不是 超時策略.Warp(重試策略) 。這是因為在超時之后 Polly 會拋出 TimeoutRejectedException 異常,在重試策略捕獲到該異常之后,就會開始重試操作,即后面組合策略的 ExecuteAsync() 方法接收的委托。

三、實現

首先我們定義一個方法,該方法用於組合策略(超時+重試),因為我這里是傳入的異步委托操作,所以返回的是 AsyncPolicy 對象。

private AsyncPolicyWrap BuildTimeoutRetryPolicy(string msg)
{
    // 超時策略,執行目標委托超過 5 秒則視為超時,拋出異常。
	var timeoutPolicy = Policy.TimeoutAsync(5);
    // 重試策略,重試 2 次,每次打印信息。
	var retryPolicy = Policy.Handle<TimeoutRejectedException>().RetryAsync(2, (exception, i) =>
	{
        Console.WriteLine("開始第 i 次重試...");
	});

	return retryPolicy.WrapAsync(timeoutPolicy);
}

定義好策略之后,就是我們的實際應用了。這里說明一下執行邏輯,當第一次請求的時候如果發生了超時的情況,則進入重試策略,重試兩次,當最后一次仍然拋出 TimeoutRejectedException 異常,則重試策略不再捕獲,直接將異常拋出給調用者。

private async Task<string> GetResult(AsyncPolicyWrap policy)
{
	try
	{
		return await policy.ExecuteAsync(() => SendDataAsync(sendProtocol));
	}
	catch (TimeoutRejectedException)
	{
		return "超時";
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM