# [NetCore] 高併發處理重試處理Polly + Jitter ###### tags: `C#` ## 介紹 [Polly](https://github.com/App-vNext/Polly)是一個OpenSource的函示庫,可透過fluent的方式去制定錯誤發生的處理規範,Jitter則是為了克服許多用戶在中斷後不斷重試,進而造成系統負擔的一個延遲策略。 ## 目錄 [TOC] # 一、前言 在工作空閒之餘想想真對以往錯誤重試的流程去優化時而發現的作法,往常在執行重試行為時只會單單使用`try/catch`,當發生錯誤時進而執行重試作業,如果有眾多的詢問並且都發生了失敗,此時則會使系統負擔直線上升,在此會針對兩方面下去優化 1. 調整 RetryCode 寫法使其更好閱讀 2. 將 Retry 加入Jitter策略克服分散尖峰壓力 進入實作之前我們先來針對重試延遲這區塊來了解 # 二、延遲策略分析 我們透過文章[Exponential Backoff And Jitter](https://aws.amazon.com/tw/blogs/architecture/exponential-backoff-and-jitter/)可以得知藉由不同的延遲時間的設定,來分散眾多Clinet彼此之間的競爭,因此延遲策略在選擇上就相對來的重要。 ## Retry with Jittered Back-off 在策略上簡單描述就是增加一個隨機數值成為等待時間,但是合為較佳的等待時間以及怎樣的隨機演算法就成為了一個重要的課題,在之後實作中我們會藉由[Polly.Contrib.WaitAndRetry](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry)套件來協助我們處理這一區塊。 實作上我會藉由套件提供的`DecorrelatedJitterBackoffV2`的延遲規則來進行,此演算法可以取得較佳的分散效果,有興趣可以查看[文章](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry#new-jitter-recommendation)內部的網友討論,裡面有針對各個不同的等待方式去跑數據,也可以查看[GitHub](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry/blob/9e63367cf6a3433ee6c29a9fb085e7d4dcd64fb7/src/Polly.Contrib.WaitAndRetry/Backoff.DecorrelatedJitterV2.cs#L22)內的原碼做更深入的了解,這邊附上套件所測式的曲線結果。  接著我們就直接進入實作環節吧 # 二、實作步驟 ## 前置作業 主要會使用要兩個套件 1. [Polly](https://github.com/App-vNext/Polly#timeout):主要定義相關事件處理 2. [Polly.Contrib.WaitAndRetry](https://github.com/Polly-Contrib/Polly.Contrib.WaitAndRetry):用來定義Delay規則 此兩個套件所提供的功能還有很多種,以下實作不會介紹太多留給大家測試 安裝好後可以緊接著往下看囉! :::info :bulb: 如果Delay規則想要自己寫,這邊第二個套件是可以不用安裝的,使用方式可參考此[文章](https://github.com/App-vNext/Polly/wiki/Retry-with-jitter) ::: ## Policy 規劃 我們先來制定要執行的重試策略,程式碼如下 ```csharp= // 重試等待規則 var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5); // 政策建立 var myPolicy = Policy .Handle<Exception>() .WaitAndRetry(delay); ``` 這邊分別做了兩件事情 1. 建立Jitter策略的延遲等待規則,並且指定重試次數為5。 2. 接收`Handle<Exception>`並且將等待規則定義給它。 定義重試規則之後接著就可以直接進行使用了 ## 使用方式 使用方式算蠻容易的同樣的直接看程式碼 ```csharp= myPolicy.Execute(() => { Console.WriteLine("Run process..."); Console.WriteLine($"Time is: {DateTime.Now}"); throw new Exception("Is Error"); }); ``` 這邊直接拋出錯誤來測試重試是否依據設定的方式來執行 其執行結果如下  與設定相同重試了五次,每次的間隔所等待的秒數 # 結論 透過Polly的函式庫可以使重試的規則與邏輯層抽離使程式碼更容易閱讀,未來在設計模式上也可已有更多的選擇,這邊也透過jitter策略來緩解系統上尖峰上的壓力,不過重試延遲策略的選擇必須評估使用數或是其架構,不是傻傻的加上去就都可以提升效能,建議可以依據個人需求下去調整。 <br/> --- 相關參考來源: [使用 IHttpClientFactory 和 Polly 原則實作指數輪詢的 HTTP 呼叫重試](https://docs.microsoft.com/zh-tw/dotnet/architecture/microservices/implement-resilient-applications/implement-http-call-retries-exponential-backoff-polly) [[NETCore] Polly 重試機制搭配 jitter 策略](https://marcus116.blogspot.com/2019/06/polly-jitter-strategy-in-aspnetcore.html) [處理 Deadlock、網路瞬斷、伺服器忙線等暫時性故障的利器 - Polly](https://blog.darkthread.net/blog/polly/) <style> .red{color: red;} </style>
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up