上一篇 [NETCore] 使用 Polly 實現重試 (Retry) 策略 分享了使用 Polly 的重試 API 幫助我們達到重試的功能,後續在尋找相關文件時看到重試時的一種策略 Jitter strategy,在高併發的情境下如果使用重試策略可能會影響到系統,若要解決用戶端因為同時間重試造成伺服器資源高峰的狀況,可以透過添加隨機時間來改善,另外在 Jitter: Making Things Better With Randomness 中也有提到此觀念
simulate synchronization emerging in previously unsynchronized systems communicating over a network. This leads to short-lived spikes in contention, and other correlated effects on the network. Their solution is to add randomness, which breaks the loop that creates synchronization.了解了重試在高併發可能造成的原因之後,也提到了解決方法是在重試時加入隨機時間,實作上相當簡單在 C# 中使用 Random 類別就可以輕鬆達到,透過以下簡單的 sample code 讓大家更容易了解,代碼內容是在每秒發送時加入 random 0-100 毫秒的隨機時間,代碼如下
Random jitterer = new Random(); for (int i = 0; i < 6; i++) { Console.WriteLine(TimeSpan.FromSeconds(1) + TimeSpan.FromMilliseconds(jitterer.Next(0, 100))); } Console.ReadKey();執行後輸出內容如下,簡單實作出 jitter 策略
Jitter Library
在 Nuget 中同樣也可以發現 jitter 相關套件,這裡推薦可以使用 jitterMagic 函式庫,可以在 Visual Studio 中透過 Nuget Package Manager 下載,搜尋 jitterMagic 後選擇後點擊 install
或者是在 Nuget Package Console 輸入下列指令
Install-Package JitterMagic使用方式相當容易,透過 Jitter.Apply 傳入起始值或是指定百分比(預設百分比為 25%),舉例來說設定初始值為 100,得到的數字會落於 75 - 125 之間
for (int i = 0; i < 10; i++) { Console.Write(Jitter.Apply(100) + ","); } // result : 124,85,103,115,104,111,85,78,123,122,API 也提供指定百分比,舉例來說指定 87% 輸出如下
for (int i = 0; i < 10; i++) { Console.Write(Jitter.Apply(100, new JitterSettings(87)) + ","); } // result : 98,168,15,174,28,46,56,101,54,60,在 JitterMagic API 也適用 double,詳細使用可以參考官方 GitHub 說明 : 傳送門
Polly Retry + Jitter Strategy
接著在把重點放回到重試機制,在上一篇 [NETCore] 使用 Polly 實現重試 (Retry) 策略 使用波麗鳥 Polly 進行重試機制,在與 Jitter 策略搭配後的代碼 (實作 Random 類別) 如下
Random jitterer = new Random(); Policy .Handle<HttpRequestException>() .OrResult<HttpResponseMessage>(result => result.StatusCode != HttpStatusCode.OK) .WaitAndRetry(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)) + TimeSpan.FromMilliseconds(jitterer.Next(0, 100)) ) .Execute(doMockHTTPRequest);可以看到代碼中第 8 行中發送時間加上 jitter 策略,讓重試時間為 2 的 n 次方 (n=第幾次重試) 加上隨機時間,改善高併發時可能影起的效能問題,如果想套用 JitterMagic 套件也可簡單替換掉,以上為分享 Polly 重試機制搭配 jitter 策略的簡單實作,若有問題歡迎一起討論,謝謝 :)
0 意見:
張貼留言