Polly的多种弹性策略介绍和简单使用

Posted jiumei1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Polly的多种弹性策略介绍和简单使用相关的知识,希望对你有一定的参考价值。

什么是Polly?
Polly是一个.NET弹性和瞬态故障处理库.允许我们以非常顺畅和线程安全的方式来执行诸如行重试,断路,超时,故障恢复等策略。

Polly项目地址:https://github.com/App-vNext/Polly

Polly提供多种弹性策略:重试(Retry),断路器(Circuit-breaker),超时检测(Timeout),缓存(Cache),降级(FallBack)

重试(Retry):

前置条件:许多故障是短暂的,并且可能在短暂延迟后自我纠正
政策如何缓解:允许配置自动重试机制

断路器(Circuit-breaker):
前置条件:当系统繁忙时,快速响应失败比让用户一直等待更好,保护故障系统不受过载的影响可以帮助它恢复
政策如何缓解:故障超过某个预先配置的阈值时,阻塞执行一段时间。

超时检测(Timeout):
前置条件:超过一定的等待,成功的结果是不可能的
政策如何缓解:保证调用者不必等待超时

隔板隔离(Bulkhead Isolation):
前置条件:当进程发生故障时,备份的多个失败调用可以轻易地淹没主机中的资源(例如线程/ CPU)。故障下游系统还可能导致上游“备份”失败的呼叫,两者都有可能导致故障过程导致更广泛的系统崩溃
政策如何缓解:将受管理的操作限制在固定的资源池中,隔离它们影响其他资源的可能性

缓存(Cache):
前置条件:不经常更新的数据。
政策如何缓解:首次加载时,把响应数据进行缓存;如果缓存中存在,则从缓存中获取数据;

降级(FallBack):
前置条件:操作仍然会失败 - 当发生这种情况时你会做什么
政策如何缓解:定义在失败时返回的替代值(或要执行的操作)

策略包装(PolicyWrap):
前置条件:不同故障需要不同的策略; 弹性意味着使用组合
政策如何缓解:允许灵活组合上述任何策略

代码示例:

重试(Retry):

            //PollyException:此类文件是我自己定义的异常类
            //Policy policy = Policy.Handle<PollyException>().Retry();  //重试一次
            //Policy policy = Policy.Handle<PollyException>().Retry(10);//重试n次,本次是重试10次
            //Policy policy = Policy.Handle<PollyException>().Retry(10, (exception, retryCount, context) => //重试n次,在每次重试时调用下面代码
            //{
            //    //每次重试都会执行这里面的代码
            //    //做些操作
            //});
            //Policy policy = Policy.Handle<PollyException>().RetryForever();  //一直重试直到成功
            Policy policy = Policy.Handle<PollyException>().WaitAndRetry(new[]
              {
                TimeSpan.FromSeconds(1),//等待1秒重试一次
                TimeSpan.FromSeconds(2),//等待2秒重试一次
                TimeSpan.FromSeconds(3) //等待3秒重试一次
              });  //重试3次,每次持续等待时间分别为1秒,2秒,3秒
            try
            {
                policy.Execute(() =>
                {
                    Console.WriteLine("开始任务");
                    int s = new Random().Next(0, 100);
                    if (s % 3 != 0)
                    {
                        throw new PollyException("出错啦-" + s);
                    }
                    Console.WriteLine("完成任务" + s);
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

  

  

 断路器(Circuit-breaker):

            ISyncPolicy policy = Policy.Handle<PollyException>().CircuitBreaker(6, TimeSpan.FromSeconds(10));
            while (true)
            {
                try
                {
                    policy.Execute(() =>
                    {
                        Console.WriteLine("开始执行");
                        int s = new Random().Next(0, 100);
                        if (s % 10 != 0)
                        {
                            throw new PollyException("出错啦-" + s);
                        }
                        Console.WriteLine("结束执行" + s);
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

                Thread.Sleep(1000);
            }
//短路保护 出现了6次故障之后,直接给我们爆出了短路保护的异常,“The circuit is now open and is not allowing calls”

  请注意,断路器策略会重新抛出所有异常,甚至是已处理的异常。断路器用于测量故障并在发生太多故障时断开电路,但不会重新编排重试。根据需要将断路器与重试策略相结合。

策略包装(PolicyWrap):

可以把多个ISyncPolicy合并到一起执行
policy3= policy1.Wrap(policy2);
执行policy3就会把policy1、 policy2封装到一起执行

            Policy policyRetry = Policy.Handle<PollyException>().Retry(3);
            Policy policyFallback = Policy.Handle<PollyException>()
            .Fallback(() =>
            {
                Console.WriteLine("降级");
            });
            Policy policy = policyFallback.Wrap(policyRetry);
            policy.Execute(() =>
            {
                Console.WriteLine("开始任务");
                int s = new Random().Next(0, 100);
                if (s % 10 != 0)
                {
                    throw new PollyException("出错-" + s);
                }
                Console.WriteLine("完成任务-" + s);
            });
//重试3次,还出错就降级

  

超时检测(Timeout):

            Policy policy = Policy.Handle<Exception>() //定义所处理的故障
            .Fallback(() =>
            {
                Console.WriteLine("执行出错");
            });
            policy = policy.Wrap(Policy.Timeout(2, TimeoutStrategy.Pessimistic));
            policy.Execute(() =>
            {
                Console.WriteLine("开始任务");
                Thread.Sleep(5000);
                Console.WriteLine("完成任务");
            });

 超时处理不能简单的链式调用 ,要用到Wrap()

 降级(FallBack):

 

           //如果正常业务代码出现异常,则执行降级业务代码
            Action fallbackAction = () =>
            {
                //执行降级业务代码
                Console.WriteLine("执行出错-降级");
            };
            Policy policy = Policy.Handle<PollyException>()
            .Fallback(fallbackAction);
            policy.Execute(() =>
            {
                //正常业务代码
                Console.WriteLine("开始任务");
                int s = new Random().Next(0, 100);
                if (s % 3 != 0)
                {
                    throw new PollyException("出错啦-" + s);
                }
                Console.WriteLine("完成任务" + s);
            });

 缓存(Cache):

 

 隔板隔离(Bulkhead Isolation):

 

 





















以上是关于Polly的多种弹性策略介绍和简单使用的主要内容,如果未能解决你的问题,请参考以下文章

Polly

使用 Polly 实现复杂策略(超时重试)

在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务

微服务之Polly熔断策略

云原生系统之弹性模式

具有悲观超时策略的 C# Polly 在多个线程上运行缓慢?