Polly Circuit Breaker 处理和未处理的异常
Polly Circuit Breaker handled and unhandled exceptions
我想使用 Polly 来实现断路器模式。
在文档中,有一个 description of the Half Open state,上面写着:
- If a handled exception is received, that exception is rethrown, and the circuit transitions immediately back to open, and remains open again for the configured timespan.
- If an unhandled exception is received, the circuit remains in half-open.
我不确定我是否理解已处理异常和未处理异常之间的区别。我们正在描述一种情况,其中操作是 运行 策略并抛出异常。
当他们说异常被处理时,他们指的是什么地方被处理了?因为正如我们所说,动作抛出它是否意味着它未处理?
搞不懂什么时候半开还是半开,什么时候过渡到开
当您定义断路器策略时,您可以定义 CB implementation 应考虑哪种类型的异常。换句话说,您可以列出那些应被视为执行失败并应计入连续失败计数的异常。
您可以结合使用 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
(包括 ArgumentNullException
和 ArgumentOutOfRangeException
)视为已处理的异常。
- 这意味着如果被调用的委托抛出这三个异常之一,那么它将增加连续失败计数,如果达到阈值,它将中断。
- 重试策略在
ArgumentException
和 NotSupportedException
的情况下被触发。
- 如果抛出其中任何一个,它将休眠一秒钟,然后尝试重新执行同一个委托。
因此,从断路器的角度来看,如果 NotSupportedException
被抛出,则不会被考虑 >> 因此名称未处理。
这就是我们的示例方法的实现方式,它会抛出 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
仅抛出 NotSupportedException
s。这不是由 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
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
因为当 CB 处于 HalfOpen
状态时 SampleCall
确实抛出 ArgumentException
这就是为什么 CB 将其视为已处理的异常并将其自身从 HalfOpen
转移到 Open
.
我想使用 Polly 来实现断路器模式。
在文档中,有一个 description of the Half Open state,上面写着:
- If a handled exception is received, that exception is rethrown, and the circuit transitions immediately back to open, and remains open again for the configured timespan.
- If an unhandled exception is received, the circuit remains in half-open.
我不确定我是否理解已处理异常和未处理异常之间的区别。我们正在描述一种情况,其中操作是 运行 策略并抛出异常。
当他们说异常被处理时,他们指的是什么地方被处理了?因为正如我们所说,动作抛出它是否意味着它未处理?
搞不懂什么时候半开还是半开,什么时候过渡到开
当您定义断路器策略时,您可以定义 CB implementation 应考虑哪种类型的异常。换句话说,您可以列出那些应被视为执行失败并应计入连续失败计数的异常。
您可以结合使用 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
(包括ArgumentNullException
和ArgumentOutOfRangeException
)视为已处理的异常。- 这意味着如果被调用的委托抛出这三个异常之一,那么它将增加连续失败计数,如果达到阈值,它将中断。
- 重试策略在
ArgumentException
和NotSupportedException
的情况下被触发。- 如果抛出其中任何一个,它将休眠一秒钟,然后尝试重新执行同一个委托。
因此,从断路器的角度来看,如果 NotSupportedException
被抛出,则不会被考虑 >> 因此名称未处理。
这就是我们的示例方法的实现方式,它会抛出 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
仅抛出 NotSupportedException
s。这不是由 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
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
因为当 CB 处于 HalfOpen
状态时 SampleCall
确实抛出 ArgumentException
这就是为什么 CB 将其视为已处理的异常并将其自身从 HalfOpen
转移到 Open
.