Polly 熔断策略

熔断策略主要以 CircuitBreaker 来完成、

工作原理

熔断器可以被看作为一个主要含有三个状态的状态机

如果以电路开关来看:

开关闭合对应 CLOSED 状态, 开关打开对应 OPEN 状态, 而 HALF OPEN 只是为了过渡处理过程中的状态变化

  • OPEN 状态, FLOW 不通
  • CLOSED 状态, FLOW 正常

CLOSED

熔断器的初始状态就是 CLOSED, 当熔断器状态为 CLOSED 的时候:

  • 所有通过策略的操作将会被执行, 熔断器也会记录这些操作的失败与成功
  • 如果通过策略执行的操作失败数到达某个设置的阈值,熔断器将会被熔断,即状态变更为 OPEN 。
    • CircuitBreaker 会在 N 次连续的操作失败被熔断
    • AdvancedCircuitBreaker 的熔断取决于失败比率
  • 对于改变熔断器状态的操作,此操作产生的原始 exception 将会被抛出, 而熔断器的状态将会变更为 OPEN

OPEN

当熔断器状态为 OPEN 的时候:

  • 所有通过策略的操作都不会被执行
  • 调用方会立刻被返回 BrokenCircuitException 异常
    • BrokenCircuitException 将包含最后试熔断器状态改变操作抛出的异常作为 InnerException
  • 熔断器打开之后, 会持续 durationOfBreak 参数配置的时间。在此时间结束之后,当下一个经过策略的操作执行或者当 CircuitState 熔断器状态被查询的时候, 熔断器的状态会变更为 HALF OPEN。

HALF OPEN

当熔断器状态为 HALF OPEN 的时候:

  • 下一个经过策略的操作将会被视作测试,用来检查熔断器的健康状态

    • 如果该操作执行的时候已经超过了 durationOfBreak 设置的熔断时间,则执行操作。熔断器在每次熔断的期间内 durationOfBreak,只允许有一次尝试操作。所有其他在 HALF OPEN 状态的操作都会被拒绝执行,并抛出 BrokenCircuitException
  • 传入 Execute() (或类似重载) 的委托方法将被尝试调用
    • 如果调用抛出了已处理的异常, 原本的异常将会被再次抛出,并且熔断器的状态会立即变更为 OPEN,持续 durationOfBreak 配置的时间。
    • 如果此操作未抛出异常,则熔断器状态变更为 CLOSED

流程图

Circuit Breaker

public static void TryBasic()
{
    var breaker = Policy
        // 设置熔断器处理的异常类型
        .Handle<Exception>()

        // 设置异常阈值 3 ,熔断持续时间 5.5 秒
        .CircuitBreaker(3, TimeSpan.FromSeconds(5.5),
                        (e, state, tspan, context)=>
                        {
                            Console.WriteLine($"OnBreak: state: {state} \r\n ex: {e.Message}");
                        },
                        context =>
                        {
                            Console.WriteLine("onReset");
                        },
                        ()=>
                        {
                            Console.WriteLine("onHalfOpen");
                        });

    var random = new Random();
    var obj = Policy<object>
        .Handle<Exception>()
        .WaitAndRetryForever(
        (times, tspan) => TimeSpan.FromSeconds(1),
        (res, times, tspan, c) =>
        {
            Console.WriteLine($"retry: {times}, breaker state: {breaker.CircuitState}");
        })

        // 组合重试与熔断策略
        .Wrap(breaker)

        .Execute(() =>
                 {
                     var val = random.Next(1, 100);
                     Console.WriteLine($"called:{val}");
                     switch (val % 9)
                     {
                         case 0:
                             return "Success";
                         default:
                             throw new Exception($"error val: {val}");
                     }
                 });

    Console.WriteLine(obj);
}

输出:

熔断器初始化状态为 CLOSED, 在产生三次异常之后,触发 OnBreak 回调, 状态也变更为了 OPEN,

在上面我们设置的熔断持续时间结束后,状态变更为了 HALF OPEN, 由重试策略执行了一次 Execute ,

called: 20

因为由引发了一次异常,导致 CircuitBreaker 再次熔断, 状态变更为 OPEN,与流程图一致。

AdvancedCircuitBreaker

public static void TryAdvanced()
        {
            var breaker = Policy
                .Handle<Exception>()

                // 设置高级熔断器
                .AdvancedCircuitBreaker(

                // 设置超过30%的失败率则熔断
                failureThreshold: 0.8,

                // 10 秒做一次采样
                samplingDuration: TimeSpan.FromSeconds(10),

                // 在采样时间内最小吞吐量
                minimumThroughput: 5,

                // 熔断持续时间
                durationOfBreak: TimeSpan.FromSeconds(10),
                onBreak: (e, state, tspan, context) =>
                {
                    Console.WriteLine($"OnBreak: state: {state} \r\n ex: {e.Message}");
                },
                onReset: context =>
                {
                    Console.WriteLine("onReset");
                },
                onHalfOpen: () =>
                {
                    Console.WriteLine("onHalfOpen");
                });

            var random = new Random();
            var obj = Policy<object>
                .Handle<Exception>()
                .WaitAndRetryForever(
                (times, tspan) => TimeSpan.FromSeconds(1),
                (res, times, tspan, c) =>
                {
                    Console.WriteLine($"retry: {times}, breaker state: {breaker.CircuitState}");
                })
                .Wrap(breaker)
                .Execute(() =>
                {
                    var val = random.Next(1, 100);
                    Console.WriteLine($"called:{val}");
                    switch (val % 9)
                    {
                        case 0:
                            return "Success";
                        default:
                            throw new Exception($"error val: {val}");
                    }
                });

            Console.WriteLine(obj);
        }

输出:

将采样时间内 samplingDuration 异常次数除以设置最小吞吐量 minimumThroughput,得到失败率,若超过设置的 failureThreshold,则触发熔断。

注意

使用 Wrap 方法组合两个或 更多策略一起监控 Execute 中执行的操作。

原文地址:https://www.cnblogs.com/rajesh/p/10775598.html

时间: 2024-08-30 16:04:00

Polly 熔断策略的相关文章

微服务之Polly熔断策略

紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间内熔断该服务的调用,熔断期间的请求将不再继续调用目标服务,而是直接返回,节约资源,提高服务的稳定性,熔断周期结束后如果目标服务情况好转则恢复调用. 注意:为了服务的稳定性,在执行需要多次 Retry重试策略的情况下( 重试策略,感兴趣的小伙伴可以查看我上一篇,或者自行搜索),最好组合熔断策略,预防可能存在的风险. 熔断状态 打开(Open) 熔

3.Hystrix源码-熔断策略

前言 强制开关 正常策略 流量探测 小结 请求统计方式 前言 上一篇讲解了hystrix四个接口的关系和调用流程,这一节主要讲解一下在住流程中熔断策略是怎样的,是如何判断应用是否该进行熔断的 强制开关 在流量进来的时候,会经过这个方法来判断现在的熔断开关状态,如果为true则允许流量通过,如果为false则进入fallback阶段 @Override public boolean allowRequest() {     if (properties.circuitBreakerForceOpe

Polly 重试策略

工作原理 Retry 基本重试: public static void Retry() { var random = new Random(); // Policy<> 泛型定义返回值类型, 如若不需要返回值, 可直接使用 Policy var obj = Policy<object> // Handle<> 可指定需要处理的异常类型 .Handle<Exception>() //也可以使用重载对Exception 进行再次过滤 //.Handle<E

Polly+AspectCore实现熔断与降级机制

Polly+AspectCore实现熔断与降级机制 https://www.cnblogs.com/edisonchou/p/9159644.html 一.熔断.降级与AOP 1.1 啥是熔断? 在广义的解释中,熔断主要是指为控制股票.期货或其他金融衍生产品的交易风险,为其单日价格波动幅度规定区间限制,一旦成交价触及区间上下限,交易则自动中断一段时间("熔即断"),或就此"躺平"而不得超过上限或下限("熔而不断"). 而对于微服务来说,熔断就是我

熔断降级(Polly)

熔断降级(Polly) https://www.cnblogs.com/qhbm/p/9224307.html 一. 什么是熔断降级 熔断就是"保险丝".当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成"雪崩",或者大量的超时等待导致系统卡死. 降级的目的是当某个服务提供者发生故障的时候,向调用方返回一个错误响应或者替代响应.举例子:调用联通接口服务器发送短信失败之后,改用移动短信服务器发送,如果移动短信服务器也失败,则改用电信短

.NET Core微服务之基于Polly+AspectCore实现熔断与降级机制

一.熔断.降级与AOP 1.1 啥是熔断? 在广义的解释中,熔断主要是指为控制股票.期货或其他金融衍生产品的交易风险,为其单日价格波动幅度规定区间限制,一旦成交价触及区间上下限,交易则自动中断一段时间("熔即断"),或就此"躺平"而不得超过上限或下限("熔而不断"). 而对于微服务来说,熔断就是我们常说的"保险丝",意为当服务出现某些状况时,切断服务,从而防止应用程序不断地常识执行可能会失败的操作造成系统的"雪崩&q

ASP.NET Core-HttpClientFactory + Polly 实现熔断降级【转】

本文主要介绍 HttpClientFactory 整合 Polly 的使用,实现对 Http 请求的超时.重试.熔断.降级等操作. HttpClientFactory 集成 Polly 创建 .NET Core API 项目(这里使用的是 .NET Core 2.2): 安装 Microsoft.Extensions.Http.Polly NuGet Package; 在 Startup.cs 的 ConfigureServices 方法中添加 HttpClient 相关代码: public v

c# polly学习

最近在项目当中使用到了开源项目polly的异常重试策略,在使用当中发现polly是个功能很强大的项目, 于是对其提供的几种策略进行学习. polly的github地址为:https://github.com/App-vNext/Polly 关于polly polly文档中对自己介绍的原文是: Polly is a .NET resilience and transient-fault-handling library that allows developers to express polic

三分钟学会.NET微服务之Polly

原文:三分钟学会.NET微服务之Polly 熔断降级是一个非常重要的概念,我们先说一下什么是熔断降级,咱们都知道服务发现,一个有问题的服务器没来得急注销过一会就崩溃掉了,那么我们的请求就有可能访问一个已经崩溃的服务器,那么就会请求失败,因为已经game over了.那么这个问题怎么解决呢,你一定要承认,这个问题是无法避免的.没有什么方法说,我拿到的服务器都没有问题,这事是不可能的,所以你要承认你会有机会拿到有问题的服务器.那么熔断降级就是来解决这种问题的. 一.什么是熔断 熔断就像是“保险丝”,