只有累積,沒有奇蹟

2019年6月10日 星期一

[NETCore] Polly 重試機制搭配 jitter 策略

Jitter 策略
上一篇 [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 毫秒的隨機時間,代碼如下
  1. Random jitterer = new Random();
  2.  
  3. for (int i = 0; i < 6; i++)
  4. {
  5. Console.WriteLine(TimeSpan.FromSeconds(1) + TimeSpan.FromMilliseconds(jitterer.Next(0, 100)));
  6. }
  7.  
  8. Console.ReadKey();
執行後輸出內容如下,簡單實作出 jitter 策略

Jitter Library
在 Nuget 中同樣也可以發現 jitter 相關套件,這裡推薦可以使用 jitterMagic 函式庫,可以在 Visual Studio 中透過 Nuget Package Manager 下載,搜尋 jitterMagic 後選擇後點擊 install 
或者是在 Nuget Package Console 輸入下列指令
  1. Install-Package JitterMagic
使用方式相當容易,透過  Jitter.Apply  傳入起始值或是指定百分比(預設百分比為 25%),舉例來說設定初始值為 100,得到的數字會落於 75 - 125 之間
  1. for (int i = 0; i < 10; i++)
  2. {
  3. Console.Write(Jitter.Apply(100) + ",");
  4. }
  5. // result : 124,85,103,115,104,111,85,78,123,122,
API 也提供指定百分比,舉例來說指定 87% 輸出如下 
  1. for (int i = 0; i < 10; i++)
  2. {
  3. Console.Write(Jitter.Apply(100, new JitterSettings(87)) + ",");
  4. }
  5. // 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 類別) 如下
  1. Random jitterer = new Random();
  2. Policy
  3. .Handle<HttpRequestException>()
  4. .OrResult<HttpResponseMessage>(result => result.StatusCode != HttpStatusCode.OK)
  5. .WaitAndRetry(5,
  6. retryAttempt =>
  7. TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))
  8. + TimeSpan.FromMilliseconds(jitterer.Next(0, 100))
  9. )
  10. .Execute(doMockHTTPRequest);
可以看到代碼中第 8 行中發送時間加上 jitter 策略,讓重試時間為 2 的 n 次方 (n=第幾次重試) 加上隨機時間,改善高併發時可能影起的效能問題,如果想套用 JitterMagic 套件也可簡單替換掉,以上為分享 Polly 重試機制搭配 jitter 策略的簡單實作,若有問題歡迎一起討論,謝謝 :)

Related Posts:

  • [.NETCore] 如何取得 appsettings.json 組態設定問題 在開發時有時會將資訊紀錄在 Web.Config 設定檔中的開發經驗,在 .NET Framework 要取得 web.config 自訂組態設定時可以透過  ConfigurationManager.AppSettings ,相信大家都有了解且不陌生;但今天場景換到 ASP.NET Core 時,在一開始建立好新專案後只有  appsettings.json  設定檔,那麼該如何… Read More
  • [IIS] IIS 站台服務異常中止 - HttpEvent 問題 今天同事反應測試主機 IIS Server 無法使用,進到 QA 主機後發現所有的 IIS 服務都已停止,第一直覺就是到事件檢視器查看是否有異常的 Log 資訊,發現事件檢視器紀錄其中來源  HttpEvent  嫌疑重大,以下就針對解決此問題的方式做說明,若有問題歡迎提出一起討論或是給予指導。 解決方案 由於公司測試機對外預設都是以 80 port 為主,無故發生異常是蠻很奇怪,過去… Read More
  • [UnitTest] 如何測試目標方法中 Guid 型別的代碼 ?情境 如果要產生一個亂數時很常會想到 Guid 方法解決,在 C# 使用 Guid 的方式相當簡單僅要透過  Guid.NewGuid  靜態方法產生一組 Guid 使用,在目前公司很常看到使用 Guid 作為識別碼,今天在重構舊代碼時忽然想到如果遇到 Guid 該如何進行加上單元測試,以下就目前想到的解法進行測試與說明,如果各位高手們有更好的方法歡迎高抬貴手一起討論研究。 解決方案 寫個簡單的 Sa… Read More
  • [VisualStudio] .NET 分析測試代碼覆蓋率 AxoCover前言  最近在替既有專案補上單元測試,除了在 SonarQube 可以看到測試代碼覆蓋率之外,這幾天同事推薦一套可以在 Visual Studio 執行的程式碼覆蓋率分析工具 AxoCover,可運行在 .NET 環境且開源免費,簡單玩了一下覺得十分不錯推薦給大家,今天就來分享 AxoCover 在 Visual Studio 2017 的安裝及基本操作說明。 安裝 AxoCover  Step 1 :… Read More
  • [IIS] 程序無法存取檔案,因為檔案正由另一個程序使用。(發生例外狀況於HRESULT:0x80070020)問題 今天要在公司測試 Server 建立測試站台,在完成設定 Application Pool 與站台指定位置後按下啟動,跳出'程序無法存取檔案,因為檔案正由另一個程序使用。(發生例外狀況於HRESULT:0x80070020) 錯誤訊息,訊息內容看似有檔案被 lock 住造成啟動異常,但追根究底之後會發現其異常原因蠻單純的,以下就針對解決此問題的方式做說明,若有問題歡迎提出一起討論或是給予指導。 解決方案 根… Read More

0 意見:

張貼留言

Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

Design by Anders Noren | Blogger Theme by NewBloggerThemes.com