紧接着上一篇说, 咱们继续介绍 https://github.com/App-vNext/Polly 这个类库
熔断策略(Circuit-breaker)
如果调用某个目标服务出现过多超时, 异常等情况, 可以采取一定时间内熔断该服务的调用, 熔断期间的请求将不再继续调用目标服务, 而是直接返回, 节约资源, 提高服务的稳定性, 熔断周期结束后如果目标服务情况好转则恢复调用.
注意: 为了服务的稳定性, 在执行需要多次 Retry 重试策略的情况下( 重试策略, 感兴趣的小伙伴可以查看我上一篇, 或者自行搜索), 最好组合熔断策略, 预防可能存在的风险.
熔断状态
打开(Open)
熔断器打开状态, 此时对目标服务的调用都直接返回错误, 熔断周期内不会走网络请求, 当熔断周期结束时进入半开状态;
关闭(Closed)
关闭状态下正常发生网络请求, 但会记录符合熔断条件的连续执行次数, 如果错误数量达到设定的阈值(如果在没有达到阈值之前恢复正常, 之前的累积次数将会归零), 熔断状态进入到打开状态;
半开(Half-Open)
半开状态下允许定量的服务请求, 如果调用都成功 (或一定比例) 则认为恢复了, 关闭熔断器, 否则认为还没好, 又回到熔断器打开状态;
熔断使用说明
- // 在连续 3 次异常后熔断, 并保持 1 分钟的熔断状态, 调用者将收到断路保护的异常信息
- Policy
- .Handle<SomeExceptionType>()
- .CircuitBreaker(3, TimeSpan.FromMinutes(1));
熔断代码测试
- private static int times = 0;
- public static void TestPolicy()
- {
- var circuitBreakerPolicy = Policy
- .Handle<Exception>()
- .CircuitBreaker(
- exceptionsAllowedBeforeBreaking: 4, // 连续 4 次异常
- durationOfBreak: TimeSpan.FromMinutes(1), // 断开 1 分钟
- onBreak: (exception, breakDelay) => // 断路器打开时
- Console.WriteLine($"熔断: {breakDelay.TotalMilliseconds } ms, 异常:" + exception.Message),
- onReset: () => // 熔断器关闭时
- Console.WriteLine("熔断器关闭了"),
- onHalfOpen: () => // 熔断时间结束时, 从断开状态进入半开状态
- Console.WriteLine("熔断时间到, 进入半开状态")
- );
- for (int i = 0; i <12; i++) // 模拟多次调用, 触发熔断
- {
- try
- {
- var result = circuitBreakerPolicy.Execute(Test);
- Console.WriteLine(result);
- }
- catch (Exception ex)
- {
- Console.WriteLine("try-catch:" + ex.Message);
- }
- Thread.Sleep(500);
- }
- }
- private static string Test()
- {
- times++;
- if (times % 5 != 0) // 模仿某些错误情况下抛异常
- {
- throw new Exception("exception message");
- }
- return "success";
- }
熔断高级配置
根据时间段内总请求数中的异常比例触发熔断:
- var advancedCircuitBreakerPolicy = Policy
- .Handle<Exception>()
- .AdvancedCircuitBreaker(
- failureThreshold: 0.5, // 至少 50% 有异常则熔断
- samplingDuration: TimeSpan.FromSeconds(10), // 10 秒内
- minimumThroughput: 8, // 最少共有多少次调用
- durationOfBreak: TimeSpan.FromSeconds(30),
- onBreak: (exception, breakDelay) => // 断路器打开时
- Console.WriteLine($"熔断: {breakDelay.TotalMilliseconds } ms, 异常:" + exception.Message),
- onReset: () => // 熔断器关闭时
- Console.WriteLine("熔断器关闭了"),
- onHalfOpen: () => // 熔断时间结束时, 从断开状态进入半开状态
- Console.WriteLine("熔断时间到, 进入半开状态")
- );
可以看到使用起来还是 挺方便简单的, 可以结合项目框架组合出不同玩法, 哈哈哈, 感兴趣的同学可以自行古哥或者度娘哈. 回见
来源: https://www.cnblogs.com/DanielYao/p/11091297.html