Polly CircuitBreakerが処理した例外と未処理の例外

Nov 24 2020

Pollyを使用してサーキットブレーカーパターンを実装したいと思います。

ドキュメントには、ハーフオープン状態の説明があり、そこには次のように書かれています。

  • 処理された例外を受信すると、その例外が再スローされ、回線はすぐに開いた状態に戻り、設定された期間、再び開いたままになります。
  • 未処理の例外が受信された場合、回路はハーフオープンのままになります。

ここで、処理された例外と処理されていない例外の違いを理解できるかどうかはわかりません。ポリシーによってアクションが実行され、例外がスローされる場合について説明します。

例外が処理されたと彼らが言うとき、彼らはそれが処理されていることをどこで意味しますか?私たちが言ったように、アクションがそれを投げたので、それはそれが処理されていないことを意味しませんか?

ハーフオープン状態がハーフオープンのままで、いつオープンに移行するのか、完全には理解できません。

回答

1 PeterCsala Nov 25 2020 at 09:20

サーキットブレーカポリシーを定義すると、CB実装で考慮すべき例外の種類を定義できます。つまり、実行の失敗として扱われ、連続する失敗のカウントにカウントされる必要がある例外をリストできます。

Handle<T>Or<T>メソッド呼び出しの組み合わせを使用して、例外のリストを定義できます。

簡単な例を使用して、この概念を詳しく調べてみましょう。

var retry = Policy
    .Handle<ArgumentException>()
    .Or<NotSupportedException>()
    .WaitAndRetry(5, _ => TimeSpan.FromSeconds(1),
        onRetry: (exception, delay, context) => Console.WriteLine($"{"Retry",-10}{delay,-10:ss\\.fff}: {exception.GetType().Name}")); var circuitBreaker = Policy .Handle<ArgumentException>() .CircuitBreaker(2, TimeSpan.FromSeconds(1), onBreak: (ex, @break) => Console.WriteLine($"{"Break",-10}{@break,-10:ss\\.fff}: {ex.GetType().Name}"),
        onReset: () => Console.WriteLine($"{"Reset",-10}"), onHalfOpen: () => Console.WriteLine($"{"HalfOpen",-10}"));
  • サーキットブレーカポリシーは、すべてArgumentExceptionのs(ArgumentNullExceptionおよびを含むArgumentOutOfRangeException)を処理された例外と見なします。
    • これは、呼び出されたデリゲートがこれら3つの例外のいずれかをスローすると、連続する失敗カウントが増加し、しきい値に達すると中断することを意味します。
  • 再試行ポリシーは、の場合ArgumentExceptionとの場合にもトリガーさNotSupportedExceptionれます。
    • これらのいずれかがスローされると、1秒間スリープしてから、同じデリゲートを再実行しようとします。

したがって、サーキットブレーカーの観点から、aNotSupportedExceptionがスローされた場合、それは>>とは見なされないため、名前は処理されません。

これは、ArgumentExceptionまたはをスローするサンプルメソッドの実装方法ですNotSupportedException

private static int count = 0;
private const int threshold = 3;
static void SampleCall()
{
    count++;
    if (count >= threshold) throw new NotSupportedException();
    throw new ArgumentException("Nothing");
}

ポリシーの使用法:

var strategy = Policy.Wrap(retry, circuitBreaker);

try
{
    strategy.Execute(SampleCall);
    Console.WriteLine("Succeeded");
}
catch (NotSupportedException)
{
    Console.WriteLine("Failed");
}

thresholdが3に設定されている場合の出力

Retry     01.000    : ArgumentException
Break     01.000    : ArgumentException
Retry     01.000    : ArgumentException
HalfOpen
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Failed

CBがそれ自体をHalfOpen状態に移行した後、SampleCallスローはNotSupportedExceptionsのみです。これはCBによって処理されないため、HalfOpen状態のままになります。

thresholdが2に設定されている場合の出力

Retry     01.000    : ArgumentException
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Failed

連続しArgumentExceptionた2つがなかったため、CBは壊れませんでした。ただし、も処理するため、再試行はトリガーされましたNotSupportedException

thresholdが4に設定されている場合の出力

Retry     01.000    : ArgumentException
Break     01.000    : ArgumentException
Retry     01.000    : ArgumentException
HalfOpen
Break     01.000    : ArgumentException
Retry     01.000    : ArgumentException
HalfOpen
Retry     01.000    : NotSupportedException
Retry     01.000    : NotSupportedException
Failed

CBが状態にあったときにSampleCallスローされArgumentExceptionたため、CBはHalfOpenそれを例外処理と見なし、からHalfOpenに転送しましたOpen