.NET フレームワーク 4.5.2 で Polly を介してサーキット ブレーカーと再試行パターンを実装しています。
私の理解が正しいかどうかを確認したい。
質問 1: ネットワークが停止し、サーキット ブレーカーが exceptionsAllowedBeforeBreaking の数に達し、オープン状態になり、durationOfBreak 期間待機した場合、サーキットは新しいリクエストに対してオープンになりますが、送信されたリクエストは例外をスローしますか?
質問 2: サーキット ブレーカーが例外をスローするのではなく、例外があったリクエストを再試行することが目的の動作である場合は、サーキット ブレーカー ポリシーに加えて再試行ポリシーを実装する必要があります。これについての私の理解では、質問 1 の動作が発生し、その後再試行が試行されるということです。
A. ネットワークが停止したり、サービスがダウンしたりして、ネットワークが復旧したり、サービスが再開したりした直後に要求を再試行することが望ましい動作である場合は、RetryForever を実行する必要があります。これを行うより良い方法はありますか?事実上、多くのブロッキングが発生しますよね?
コードに関しては、私のポリシーは現在次のように定義されています。
const int maxRetryAttempts = 3;
const int exceptionsAllowedBeforeBreaking = 2;
const int pauseBetweenFailures = 2;
readonly Policy retryPolicy = Policy
.Handle<Exception>()
.RetryAsync(maxRetryAttempts, (exception, retryCount) => System.Diagnostics.Debug.WriteLine($"Retry {retryCount}"));
readonly Policy circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreakerAsync(exceptionsAllowedBeforeBreaking: exceptionsAllowedBeforeBreaking,
durationOfBreak: TimeSpan.FromSeconds(pauseBetweenFailures),
onBreak: (e, span) => System.Diagnostics.Debug.WriteLine("Breaking circuit for " + span.TotalMilliseconds + "ms due to " + e.Message),
onReset: () => System.Diagnostics.Debug.WriteLine("Trial call succeeded: circuit closing again."),
onHalfOpen: () => System.Diagnostics.Debug.WriteLine("Circuit break time elapsed. Circuit now half open: permitting a trial call."));
私の呼び出しコードは次のように行われます:
var response = await retryPolicy.WrapAsync(circuitBreakerPolicy).ExecuteAsync(() => this.client.SendAsync<TData, JObject>(message, cancel, jsonSerializer));
サーキット ブレーカーですべての再試行を実行するのに必要な時間を過ぎてネットワークを切断すると、CancellationToken がキャンセルに設定され、その時点ですべての要求が失敗することがわかりました。それが起こる前にネットワークが復元された場合、リクエストは再試行されます。