文章目录
- 概述
- 服务熔断、服务降级、服务限流、流量削峰、错峰、服务雪崩
- Polly的基本使用
- 超时策略
- 悲观策略
- 乐观策略
- 重试策略
- 请求异常
- 响应异常
- 降级策略
- 熔断策略与策略包裹(多种策略组合)
- 参考
概述
Polly是一个被.NET基金会支持认可的框架,同时也是一个.NET弹性和瞬态故障处理库。它允许开发人员以流畅和线程安全的方式表达多种策略,包括重试(Retry)、断路器(Circuit Breaker)、超时(Timeout)、舱壁隔离(Bulkhead Isolation)和回退(Fallback)等。这些策略在应对瞬时故障和网络问题时非常有用,可以帮助提高应用程序的可用性和稳定性。
Polly框架的价值在于它为微服务场景提供了强大的支持。在微服务架构中,服务之间的调用关系复杂,状态难以掌控。Polly框架可以帮助开发人员更好地管理和监控微服务,包括调用拓扑关系、各服务节点运行存活状态、日志收集分析、异常调用追踪以及网络实况监控等。
此外,Polly框架还提供了对HTTP请求的重试机制,可以对指定异常进行特殊处理,并封装了多种恢复策略,使得开发人员能够更灵活地应对各种故障情况。
总之,Polly框架是一个功能强大且灵活的.NET库,它可以帮助开发人员更好地处理瞬态故障和提高应用程序的可用性,特别是在微服务场景中,Polly框架的价值更加凸显。
服务熔断、服务降级、服务限流、流量削峰、错峰、服务雪崩
服务雪崩
在微服务中,服务A调用服务B,服务B可能会调用服务C,服务C又可能调用服务D等等,这种情况非常常见。如果服务D出现不可用或响应时间过长,就会导致服务C原来越多的线程处于网络调用等待状态,进而影响到服务B,再到服务A等,最后会耗尽整个系统的资源,导致整体的崩溃,这就是微服务中的“雪崩效应”。
服务熔断、服务降级、服务限流、流量削峰、错峰请阅读:
【服务治理】服务熔断、服务降级、服务限流、流量削峰、错峰
Polly的基本使用
//当我们的代码触发HttpRequestException异常时,才进行处理。
Policy.Handle<HttpRequestException>();
//只有触发SqlException异常,并且其异常号为1205的时候才进行处理
Policy.Handle<SqlException>(ex => ex.Number == 1205)
//使用 Or<T> 来实现同时处理多种异常
Policy
.Handle<HttpRequestException>()
.Or<OperationCanceledException>()
//根据返回结果进行故障定义
Policy.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound)
var policy = /*策略定义*/;
var res = await policy.ExecuteAsync(/*业务代码*/);
//指定多个策略
Policy.Wrap(retry, breaker, timeout).ExecuteAsync(/*业务代码*/);
//或者
Policy.Wrap(waitAndRetry.Wrap(breaker)).ExecuteAsync(action);
接下来继续介绍几种主要的策略
创建了一个控制台项目PollyConsole用于演示,访问的服务为ServiceA项目。
项目安装Nuget包:
超时策略
Polly 中关于超时的两个策略:一个是悲观策略(Pessimistic),一个是乐观策略(Optimistic)。其中,悲观策略超时后会直接抛异常,而乐观策略则不会,而只是触CancellationTokenSource.Cancel函数,需要等待委托自行终止操作。一般情况下,我们都会用悲观策略。
代码演示:
我们这里设置了一个超时时间不能超过 5 秒(方便测试),否则就认为是错误的结果的超时策略场景。
悲观策略
执行回调,抛异常
乐观策略
执行效果,不会抛异常
重试策略
请求异常
当发生 HttpRequestException 的时候触发 RetryAsync 重试,并且最多重试3次
当前并不存在 /polly/1 api 所以用来模拟重试策略,看看执行效果:
响应异常
当请求结果为 Http Status_Code 500 的时候进行3次重试,我们先在ServiceA服务添加测试接口,然后在PollyConsole项目请求接口,完成测试效果。
PollyConsole
看看执行效果:
降级策略
策略模拟逻辑:
首先我们使用 Policy 的 FallbackAsync(“FALLBACK”) 方法设置降级的返回值。当我们服务需要降级的时候会返回 “FALLBACK” 的固定值。
同时使用 WrapAsync 方法把重试策略包裹起来。这样我们就可以达到当服务调用失败的时候重试3次,如果重试依然失败那么返回值降级为固定的 “FALLBACK” 值。
首选我们先正常访问
然后我们停掉被访问的服务 ServiceA
熔断策略与策略包裹(多种策略组合)
首先定义熔断策略
然后定义重试策略与降级策略并进行策略包裹
定义降级方法(模拟)与最终测试方法
策略模拟逻辑:
发送请求,观察请求结果,当请求出现异常的时候会进行三次重试,重试后还不行,就会打开断路器10s,10s内不会往服务端发送任何请求,只会请求降级方法,10s后为断路器改为半开状态,会尝试释放部分流量去服务端,再次观察请求结果…
看看测试效果(当前模拟服务不通的情况):
然后启动被请求的服务,模拟在服务正常情况下的效果:
到这里,我们对于几种策略的演示就差不多大功告成了。如有理解不对的地方还请告知。
本文只是基本的策略演示,实际项目需要结合HttpClientFactory 使用。
参考
.Net6 微服务之Polly入门看这篇就够了