什么是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):
原文地址:https://www.cnblogs.com/jiumei1/p/9340408.html