没有调用Polly断路器

时间:2017-12-22 14:57:01

标签: circuit-breaker polly

我正在尝试首次实现断路器,但它无法正常工作。后备政策有效,但我似乎无法达到断路器。我在不同的版本中试过这个,包括断路器的重试策略,但似乎并不重要。我确信这是我错过的基本内容。

以下是用于测试目的的代码的简化版本:

var timeoutPolicy = Policy
            .TimeoutAsync(
                _settings.TimeoutWhenCallingApi,
                TimeoutStrategy.Pessimistic
            );

        var circuitBreaker = Policy
            .Handle<TimeoutRejectedException>()
            .CircuitBreakerAsync(
                _settings.ConsecutiveExceptionsAllowedBeforeBreaking,
                _settings.DurationOfBreak
            )
            .WrapAsync(timeoutPolicy);

        policy = Policy
            .Handle<Exception>()
            .FallbackAsync(
                async cancellationToken => { Console.WriteLine("fallback triggered"); })
            .WrapAsync(circuitBreaker);

        await policy.ExecuteAsync(() => Task.Delay(-1));

1 个答案:

答案 0 :(得分:1)

策略的构建没有任何问题,断路器正在执行。

以下代码示例构造的超时,断路器和回退策略与您问题中发布的原始代码基本相同。

using Polly; 
using System;
using System.Threading.Tasks;

public class Program
{
  public static async void Main() {

    var timeoutPolicy = Policy
        .TimeoutAsync(
            TimeSpan.FromMilliseconds(10), // _settings.TimeoutWhenCallingApi,
            Polly.Timeout.TimeoutStrategy.Pessimistic
        );

    var circuitBreaker = Policy
        .Handle<Polly.Timeout.TimeoutRejectedException>()
        .CircuitBreakerAsync(
            1, // _settings.ConsecutiveExceptionsAllowedBeforeBreaking,
            TimeSpan.FromSeconds(30) // _settings.DurationOfBreak
        );
    var circuitBreakerWrappingTimeout = circuitBreaker
        .WrapAsync(timeoutPolicy);

    var policy = Policy
        .Handle<Exception>()
        .FallbackAsync(
            async cancellationToken => { Console.WriteLine("fallback triggered"); })
        .WrapAsync(circuitBreakerWrappingTimeout);

    Console.WriteLine("Circuit state before execution: " + circuitBreaker.CircuitState);

    await policy.ExecuteAsync(() => Task.Delay(-1));

    Console.WriteLine("Circuit state after execution: " + circuitBreaker.CircuitState);
  }
}

可以使用此dotnetfiddle示例运行代码:https://dotnetfiddle.net/m9O3cg

(dotnetfiddle示例更改为非异步主要因为dotnetfiddle并不总是await async Main()方法完成,所以输出并不总是完成async Main()

输出结果为:

Circuit state before execution: Closed
fallback triggered
Circuit state after execution: Open

这表明正在执行/参与执行电路断路器政策。

  • 执行的委托由超时策略超时,该策略抛出TimeoutRejectedException
  • 断路器策略捕获并计算它经历的连续TimeoutRejectedException的数量:1。这足以断开,因此断路器转换到开路状态。
  • 断路器重新抛出TimeoutRejectedException(它只是一个测量和破坏设备)
  • 后备政策捕获TimeoutRejectedException并输出后备。
  • 最终线路输出电路状态表明断路器受到呼叫的影响(参与其中)。

PolicyWrap wiki中可以看到PolicyWrap中这类流动的图解示例

由于电路处于打开状态,30秒policy内的durationOfBreak内的另一次执行将因BrokenCircuitException而失败。