ヒント
このコンテンツは eBook の「コンテナー化された .NET アプリケーションの .NET マイクロサービス アーキテクチャ」からの抜粋です。.NET Docs で閲覧できるほか、PDF として無料ダウンロードすると、オンラインで閲覧できます。
指数のバックオフでの再試行のためのアプローチとしては、オープン ソースである Polly ライブラリのような高度な .NET ライブラリを利用することをお勧めします。
Polly とは、回復機能と一時的な障害処理の機能を提供する .NET ライブラリです。 このような機能は、再試行、遮断器、バルクヘッド分離、タイムアウト、フォールバックなどの Polly ポリシーを適用することで実装できます。 Polly は .NET Framework 4.x と .NET Standard 1.0、1.1、および 2.0 (.NET Core 以降をサポート) を対象としています。
次の手順では、前のセクションで説明した、IHttpClientFactory
に統合された Polly で HTTP 再試行を使用する方法を示します。
.NET パッケージをインストールする
まず、Microsoft.Extensions.Http.Polly
パッケージをインストールする必要があります。
- Visual Studio を使用してインストールする
- dotnet CLI を使用してインストールする
- nuget.exe CLI を使用してインストールする
- パッケージ マネージャー コンソール (PowerShell) を使用してインストールする
.NET 8 パッケージの参照
IHttpClientFactory
は .NET Core 2.1 以降で使用できますが、最新の .NET 8 パッケージを NuGet から入手し、プロジェクトで使用することをお勧めします。 また、通常は Microsoft.Extensions.Http.Polly
拡張機能パッケージを参照する必要もあります。
アプリの起動時に Polly の再試行ポリシーでクライアントを構成する
AddPolicyHandler() メソッドは、使用する HttpClient
オブジェクトにポリシーを追加します。 この場合、指数バックオフを含む HTTP 再試行に対して Polly のポリシーが追加されます。
手法のモジュール性を高めるには、次のコードで示すように、Program.cs ファイル内の個別のメソッドに Http 再試行ポリシーを定義できます。
static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
return HttpPolicyExtensions
.HandleTransientHttpError()
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
.WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
retryAttempt)));
}
前のセクションで示したように、名前付きまたは型指定されたクライアント HttpClient 構成を標準の Program.cs アプリ構成内に定義する必要があります。 ここで、次のように、エクスポネンシャル バックオフを使った Http 再試行のポリシーを指定して増分コードを追加します。
// Program.cs
builder.Services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes
.AddPolicyHandler(GetRetryPolicy());
Polly では、再試行回数を指定した再試行ポリシー、指数バックオフの構成、HTTP 例外が発生した場合に実行するアクション (エラーの記録など) を定義できます。 上記のコードでは、指数関数的再試行で (最初は 2 秒) 6 回試すようにポリシーが構成されています。
再試行ポリシーにジッタ方式を追加する
通常の再試行ポリシーは、コンカレンシーやスケーラビリティが高い場合や、高競合状態下でシステムに影響を及ぼすことがあります。 部分的な停止で多くのクライアントから来る同様の再試行のピークを乗り越えるための賢い回避策は、ジッタ方式を再試行アルゴリズムまたはポリシーに追加することです。 この戦略により、エンドツーエンド システムの全体的なパフォーマンスを向上させることができます。 Polly: Retry with Jitter (ジッタで再試行) で推奨されているように、指数バックオフでの初期再試行遅延の中央値を適切に制御して、スムーズで均等に分散された再試行間隔を適用することで、優れたジッタ戦略を実施できます。 この方法は、問題が発生したときにスパイクを分散させることができます。 この原則を次の例で示します。
var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);
var retryPolicy = Policy
.Handle<FooException>()
.WaitAndRetryAsync(delay);
その他の技術情報
再試行パターンhttps://learn.microsoft.com/azure/architecture/patterns/retry
Polly と IHttpClientFactoryhttps://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory
Polly (.NET の復元および一時的な障害処理ライブラリ)https://github.com/App-vNext/Polly
Polly: ジッターで再試行https://github.com/App-vNext/Polly/wiki/Retry-with-jitter
Marc Brooker. ジッタ: ランダム性を使って状況を改善する https://brooker.co.za/blog/2015/03/21/backoff.html
.NET