0

我有以下RetryCircuit Breaker政策:

var waitAndRetryPolicy = Policy
    .Handle<Exception>(e => e is MycustomException)
    .WaitAndRetryForeverAsync(
        attempt => TimeSpan.FromMilliseconds(500),
        (exception, calculatedWaitDuration) =>
        {
            _logger.LogInfo(exception.GetType().FullName);
            _logger.LogInfo(".Log,then retry: " + exception.Message);
        });

var circuitBreakerPolicy = Policy
    .Handle<Exception>()
    .CircuitBreakerAsync(
        4,
        TimeSpan.FromSeconds(10),
        (ex, breakDelay) =>
        {
            _logger.LogError(".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!");
        },
        () => { _logger.LogError(".Breaker logging: Call ok! Closed the circuit again!"); },
        () => { _logger.LogError(".Breaker logging: Half-open: Next call is a trial!"); }
    );

return waitAndRetryPolicy.WrapAsync(circuitBreakerPolicy);

如果我使用自定义异常,则在记录以下内容后重试失败:

  • 断路器记录:断开电路 10000 毫秒!

如果我使用标准Exception类型,它工作正常。即使断路器打开,重试也会触发:

 var waitAndRetryPolicy = Policy
.Handle<Exception>()
.WaitAndRetryForeverAsync(
    attempt => TimeSpan.FromMilliseconds(500),
    (exception, calculatedWaitDuration) =>
    {
        _logger.LogInfo(exception.GetType().FullName);
        _logger.LogInfo(".Log,then retry: " + exception.Message);
    });
4

1 回答 1

1

当断路器打开时,所有后续请求都会立即被拒绝,并带有BrokenCircuitException. 这意味着如果重试在断路器打开的这段时间内触发,那么如果您只查找自定义异常,它将不会处理它。这就是为什么您的弹性策略到此结束并引发异常的原因。

如果你想对两者都应用重试(当断路器打开并且抛出自定义异常时),那么你必须使用Or<>构建器函数。

var waitAndRetryPolicy = Policy
    .Handle<Exception>(e => e is MycustomException)
    .Or<BrokenCircuitException>
    .WaitAndRetryForeverAsync(
        attempt => TimeSpan.FromMilliseconds(500),
        (exception, calculatedWaitDuration) =>
        {
            _logger.LogInfo(exception.GetType().FullName);
            _logger.LogInfo(".Log,then retry: " + exception.Message);
        });

请记住,时间在这里很重要。您的断路器会等待 10 秒,然后才会自行转换为半开状态。在此期间,重试将尝试执行多次尝试,但它们会立即失败。每次尝试失败后,它都会休眠 500 毫秒。这意味着在 10 秒内(断路器打开时),重试执行约 20 次尝试,但立即失败。

于 2020-07-03T08:31:07.730 回答