当您定义断路器策略时,您可以定义断路器应考虑哪种类型的异常CB 实施 https://github.com/App-vNext/Polly/blob/52968c25f2e13e2708898174c15aafc9cb915020/src/Polly/CircuitBreaker/AsyncCircuitBreakerEngine.cs。换句话说,您可以列出那些应被视为执行失败并应计入连续失败计数的异常。
您可以使用以下组合来定义例外列表Handle<T>
and 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}"));
- The circuit breaker policy considers all
ArgumentException
s (including ArgumentNullException
and ArgumentOutOfRangeException
) as handled exception.
- 这意味着,如果被调用的委托抛出这三个异常之一,那么它将增加连续失败计数,如果达到阈值,那么它将中断。
- The retry policy is triggered in case of
ArgumentException
and in case of NotSupportedException
as well.
- 如果抛出其中任何一个,那么它将休眠一秒钟,然后尝试重新执行同一个委托。
因此,从断路器的角度来看,如果NotSupportedException
被抛出而不是不会被考虑 >> 因此名称为未处理。
这就是我们的示例方法的实现方式,它将抛出一个ArgumentException
or a 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
仅抛出NotSupportedException
s。这不是由 CB 处理的,这就是它保留在HalfOpen
state.
输出时threshold
设置为 2
Retry 01.000 : ArgumentException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Retry 01.000 : NotSupportedException
Failed
CB没有破发,因为没有连续两次破发ArgumentException
。但重试确实触发了,因为它还处理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
因为SampleCall
确实扔了ArgumentException
当 CB 处于HalfOpen
状态这就是为什么 CB 认为已处理异常并将其自身从HalfOpen
to Open
.