C#调用Polly库实现捕捉异常处理的操作代码
作者:一个专注写bug的小白猿
一、Polly介绍
官方对 Polly 的介绍是这样的:
Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.
翻译过来大概意思是:Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以 Fluent 和线程安全的方式来实现重试、断路、超时、隔离和回退策略。
二、Polly 的七种策略
Polly 可以实现重试、断路、超时、隔离、回退和缓存策略
1、重试(Retry)
出现故障自动重试
//捕捉到错误,自动重试三次 Policy.Handle<Exception>() .Retry(3, (exception, retryCount) => { Console.WriteLine(DateTime.Now + $"代码异常: {exception},开始第 {retryCount} 次重试。"); });
2、 断路(Circuit-breaker)
当系统遇到严重问题时,快速回馈失败比让用户/调用者等待要好,限制系统出错的体量,有助于系统恢复。比如,当我们去调一个第三方的 API,有很长一段时间 API 都没有响应,可能对方服务器瘫痪了。如果我们的系统还不停地重试,不仅会加重系统的负担,还会可能导致系统其它任务受影响。所以,当系统出错的次数超过了指定的阈值,就要中断当前线路,等待一段时间后再继续。
//捕捉到同一个异常两次时,就停下来,等待 1 分钟后再继续 Policy.Handle<SomeException>() .CircuitBreaker(2, TimeSpan.FromMinutes(1));
3、 超时(Timeout)
当系统超过一定时间的等待,我们就几乎可以判断不可能会有成功的结果。比如平时一个网络请求瞬间就完成了,如果有一次网络请求超过了 30 秒还没完成,我们就知道这次大概率是不会返回成功的结果了。因此,我们需要设置系统的超时时间,避免系统长时间做无谓的等待。
//这里设置了超时时间不能超过 30 秒,否则就认为是错误的结果,并执行回调 Policy.Timeout(30, onTimeout: (context, timespan, task) => { Console.WriteLine("30秒无响应,需要执行的逻辑"); });
4、 隔离(Bulkhead Isolation)
当系统的一处出现故障时,可能促发多个失败的调用,很容易耗尽主机的资源(如 CPU)。下游系统出现故障可能导致上游的故障的调用,甚至可能蔓延到导致系统崩溃。所以要将可控的操作限制在一个固定大小的资源池中,以隔离有潜在可能相互影响的操作。
//这个策略是最多允许 10 个线程并发执行,如果执行被拒绝,则执行回调 Policy.Bulkhead(10, context => { Console.WriteLine("当前线程超过10个,需要执行的逻辑"); });
5、 回退(Fallback)
有些错误无法避免,就要有备用的方案。这个就像浏览器不支持一些新的 CSS 特性就要额外引用一个 polyfill 一样。一般情况,当无法避免的错误发生时,我们要有一个合理的返回来代替失败。
//当用户没有填写名称时,我们就给他一个默认名称,这种策略可以这样定义: Policy.Handle<Whatever>() .Fallback<User>(() => User.GetDefaultName())
6、 缓存(Cache)
一般我们会把频繁使用且不会怎么变化的资源缓存起来,以提高系统的响应速度。如果不对缓存资源的调用进行封装,那么我们调用的时候就要先判断缓存中有没有这个资源,有的话就从缓存返回,否则就从资源存储的地方(比如数据库)获取后缓存起来,再返回,而且有时还要考虑缓存过期和如何更新缓存的问题。Polly 提供了缓存策略的支持,使得问题变得简单。
//这是官方的一个使用示例用法, //它定义了缓存 5 分钟过期的策略,然后把这个策略应用在指定的 Key(即 `FooKey`)上。 var memoryCacheProvider = new MemoryCacheProvider(myMemoryCache); var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5)); TResult result = cachePolicy.Execute(context => getFoo(), new Context("FooKey"));
7、 策略包(Policy Wrap)
一种操作会有多种不同的故障,而不同的故障处理需要不同的策略。这些不同的策略必须包在一起,作为一个策略包,才能应用在同一种操作上。也就是 Polly 的弹性,即各种不同的策略能够灵活地组合起来。
//先是把预先定义好的多种不同的策略包在一起,作为一个整体策略,然后应用在同一个操作上。 var policyWrap = Policy .Wrap(fallback, cache, retry, breaker, timeout, bulkhead); policyWrap.Execute(() => { Console.WriteLine("多种策略共同执行的逻辑"); });
三、简单代码示例
备注:先引入Nuget包(Polly)
//创建一个策略,用于处理异常,并进行重试 public static Policy policy = Policy.Handle<Exception>() .Retry(3, (exception, retryCount) => { Console.WriteLine(DateTime.Now + $"代码异常: {exception},开始第 {retryCount} 次重试。"); }); public async Task Execute() { //重试机制 policy.Execute(() => //这里接收一个委托方法,也就是捕捉到异常之后要执行的业务逻辑 { Console.WriteLine("重试"); }); }
以上就是C#调用Polly库实现捕捉异常处理的操作代码的详细内容,更多关于C# Polly库捕捉异常的资料请关注脚本之家其它相关文章!