欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-26 10:13:21
什么是Polly? Polly是一个.NET弹性和瞬态故障处理库.允许我们以非常顺畅和线程安全的方式来执行诸如行重试,断路,超时,故障恢复等策略。 Polly项目地址:https://github.com/App-vNext/Polly Polly提供多种弹性策略:重试(Retry),断路器(Cir ......

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

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):