Polly瞬态故障处理熔断降级用法
2024-09-08
41
Polly是一个被.NET基金会认可的弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略,其主要功能如下:重试(Retry)断路器(Circuit-Breaker)超时检测(Timeout)缓存(Cache)降级(Fallback)。
首先通过NuGet安装Polly,我当前使用的是最新7.2.1版本的Polly。
Polly的基本使用方法:定义故障,当发生了HttpRequestException异常的时候,就会触发策略。指定策略。
以下示例代码,定义了在执行某业务代码时如果出现HttpRequestException异常就是出现故障,会触发降级策略。
Policy.Handle<HttpRequestException>().
Fallback(()=> {
// 降级方法
}).Execute(()=> {
// 业务方法,一般是跨服务的调用,可以合HttpClient结合使用
throw new HttpRequestException();
});
Polly故障的定义方法
// 单个异常的故障
Policy.Handle<Exception>();
// 带条件的异常类型
Policy.Handle<Exception>(ex => ex.Message.Contains("xxx"));
// 多个异常类型带条件
Policy.Handle<HttpRequestException>(ex => ex.Message.Contains("xxx"))
.Or<ArgumentException>()
.Or<NetworkInformationException>();
注意:Polly是故障处理库,一般定义服务调用环节产生的不可控的异常作为故障(请求出错等不可控的异常)。业务代码出现异常不需要Polly。
Polly弹性策略
// 默认重试一次
Policy.Handle<Exception>().Retry();//.Execute(() => { });
// 重试N次
Policy.Handle<Exception>().Retry(3, (ex, i) =>
{
//委托,可以做一些日志记录等操作
});
// 无限重试直到成功(不推荐)
Policy.Handle<Exception>().RetryForever();
// 重试且等待
Policy.Handle<Exception>().WaitAndRetry(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(1)
});
// 重试且等待2的i(次数)次方
Policy.Handle<Exception>().WaitAndRetry(3, i => TimeSpan.FromSeconds(Math.Pow(2, i)));
// 每一种策略最后一个参数都是一个委托,这个委托就是异常委托
// 断路器,非常使用的策略
// 连续触发了指定(2)次数的故障后,就开启断路器(OPEN),进入熔断状态,1分钟
// 断路器有三种状态,OPEN CLOSED HALF-OPEN
var breaker = Policy.Handle<HttpRequestException>().CircuitBreaker(2, TimeSpan.FromMinutes(1),
(exception,span)=> { },//OPEN 断路器开启
()=> { });//CLOSE 断路器关闭
//breaker.CircuitState = Polly.CircuitBreaker.CircuitState.Closed;
//breaker.CircuitState = Polly.CircuitBreaker.CircuitState.HalfOpen;
//breaker.CircuitState = Polly.CircuitBreaker.CircuitState.Open;
// 这个不是断路器模式的状态,这个是Polly断路器策略里的一种特殊状态
// 手动的打开断路器,断路器:手动开启状态
//breaker.CircuitState = Polly.CircuitBreaker.CircuitState.Isolated;
// 手动开启断路器,断路器默认是关闭的
breaker.Isolate();
// 手动关闭断路器
breaker.Reset();
// 如果再故障采样持续时间内,导致处理异常的操作的比例超过故障阈值,则发生熔断
// 前提是再次期间,通过断路器的操作的数量至少是最小吞吐量
Policy.Handle<HttpRequestException>().AdvancedCircuitBreaker(
0.5,// 故障阈值,50%
TimeSpan.FromSeconds(10),// 故障采样时间,10秒
8,// 最小吞吐量,10秒内最少执行了8次操作
TimeSpan.FromSeconds(30)// 熔断时间,30秒
);
// 熔断30秒后,变成HALF-OPEN,半开启状态,
// 断路器会尝试着释放(1次)操作,如果成功就变成CLOSE,如果失败断路器打开OPEN(30秒)
// 超时,服务调用慢也是故障,自己定义n秒
// 不会用单独策略,只会用策略组合
// 超时不需要定义故障
Policy.Timeout(3, (context, span, arg3, arg4) =>
{
// arg4 is TimeoutRejectedException
// 委托可选
}).Execute(() => { });
// 舱壁隔离,通过控制并发数量来管理负载。主动式策略也不需要定义故障
// 最大并发数12,超过12的都拒绝掉
Policy.Bulkhead(12).Execute(()=> { });
// 超过12个的最多20个等待
Policy.Bulkhead(12,20).Execute(() => { });
// 缓存比较复杂,以来其他库,集合Redis
// Policy.Cache()
Polly策略包装 策略组合
// 降级策略
var fullback = Policy.Handle<Exception>().
Fallback(() =>
{
Console.WriteLine("Polly Fallback!");
});
// 重试策略
var retry = Policy.Handle<Exception>().Retry(3, (ex, i) =>
{
Console.WriteLine($"retryCount:{i}");
//委托,可以做一些日志记录等操作
});
// 如果重试3次仍然发生故障就降级
var policy = Policy.Wrap(fullback, retry);
policy.Execute(() => {
Console.WriteLine("Polly Begin");
throw new Exception("Error");
});
策略组合运行结果:
更新于:4个月前赞一波!
相关文章
文章评论
评论问答