【问题标题】:WaitRetryForever is not working for a customexception in Polly.Net ResiliencyWaitRetryForever 不适用于 Polly.Net Resiliency 中的自定义异常
【发布时间】:2020-07-02 13:57:51
【问题描述】:

我有以下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);
    });

【问题讨论】:

    标签: c# polly resiliency


    【解决方案1】:

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

    如果您想对两者都应用重试(当断路器打开并且引发自定义异常时),那么您必须使用 Or&lt;&gt; 构建器函数。

    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 次尝试,但立即失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-06
      • 1970-01-01
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多