.NET的弹性及瞬间错误处理库Polly
本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly)
什么是Polly?

Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及线程安全的方式执行重试(Retry),断路器(Circuit),超时(Timeout),隔板隔离(Bulkhead Isolation)及后背策略(Fallback)。
Polly适用于.NET 4.0, .NET 4.5及.NET Standard 1.1(覆盖.NET Core, Mono, Xamarin.IOS, Xamarin.Android, UWP, WP 8.1+)。
安装Polly
.NET 4.0版本
Install-Package Polly.Net40Async
.NET 4.5及以上版本, .Net Standard 1.1
Install-Package Polly
弹性策略
Polly提供多种弹性策略。
重试策略
前提
程序会产生许多瞬时故障,但是在一定时间延迟之后,程序会自动纠正故障。
实现效果
允许配置自动重试。
断路器策略
前提
当系统发生严重故障时,快速响应请求失败比让用户等待要好。 避免故障系统过载有助于恢复系统。
实现效果
当系统错误超过预配置的数量,系统将断路一段时间。
超时策略
前提
超出一定时间的等待,想要得到正确的结果是不太可能的。
实现效果
保证调用者不需要等待超时。
隔板隔离
前提
当进程出现故障,多个失败的请求很容易占满服务器资源(线程/CPU)。 一个处于故障状态的下游系统,也会导致其上游系统故障。
实现效果
将严格管控故障进程,使其使用固定大小的资源池,隔离他们对其他进程的潜在影响
缓存策略
前提
一定比例的请求可能是相似的。
实现效果
从缓存中提供已知的响应。 当第一次读取的时候,将响应自动缓存起来。
后备策略
前提
当故障依然存在的时候,你打算做什么。
实现效果
当程序依然发生故障时,执行指定操作。
包装策略
前提
不同的故障需要不同的策略。包装策略即组合策略。
实现效果
允许灵活的将以上任意几种策略组合在一起。
如何使用Polly进行故障/异常处理?
Polly处理故障/异常有以下几个步骤。
- 指定处理的异常/故障类型
- [可选] 指定处理的异常返回值
- 指定处理策略
- 执行策略
指定处理异常/故障的类型
Polly使用Policy类的泛型方法Handle指定Polly需要处理异常/故障的类型。
指定单个异常类型
Policy.Handle<DivideByZeroException>()
指定带条件的异常类型
Policy.Handle<SqlException>(ex => ex.Number == 1205)
Polly也支持指定多种异常/故障类型, 这里需要使用Or方法
Policy.Handle<DivideByZeroException>().Or<ArgumentException>()
指定多个带条件的异常类型
Policy
.Handle<SqlException>(ex =ex.Number == 1205)
.Or<ArgumentException>(ex =ex.ParamName == "example")
Polly也支持指定内部异常
Policy
.HandleInner<HttpResponseException>()
.OrInner<OperationCanceledException>(ex => ex.CancellationToken == myToken)
指定处理的异常返回值
Polly除了支持处理异常/故障类型,还支持处理异常返回值。所谓的处理异常结果,就是当Polly监控的方法,返回某些特定结果时, Polly会触发异常/故障处理策略。
Polly使用Policy类的泛型方法HandleResult制定Polly需要处理的异常结果.
指定触发异常/故障处理策略的返回值
例如:当某个方法的返回值类型是HttpResposneMessage, 并且返回值的StatusCode是NotFound时,触发异常/故障处理策略。
Policy
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound)
指定多个返回值
Policy
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.BadGateway)
同时指定异常类型和返回值
HttpStatusCode[] httpStatusCodesWorthRetrying = {
HttpStatusCode.RequestTimeout, // 408
HttpStatusCode.InternalServerError, // 500
HttpStatusCode.BadGateway, // 502
HttpStatusCode.ServiceUnavailable, // 503
HttpStatusCode.GatewayTimeout // 504
};
HttpResponseMessage result = Policy
.Handle<HttpResponseException>()
.OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
指定异常处理策略
重试策略
重试一次
Policy
.Handle<DivideByZeroException>()
.Retry()
重试多次
Policy
.Handle<DivideByZeroException>()
.Retry(3)
重试多次,每次重试触发一个行为
Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount) =>
{
// do something
});
永久重试(直到成功)
永久重试
Policy
.Handle<DivideByZeroException>()
.RetryForever()
永久重试,每次重试触发一个行为
Policy
.Handle<DivideByZeroException>()
.RetryForever(exception =>
{
// do something
});
等待并重试
指定每个重试的间隔时间
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
});
在这个例子如果第一次出现异常,会在1秒后重试,如果依然出现异常,会在再次出现异常后2秒继续重试,以此类推,下次异常后3秒继续重试
每次重试,触发一个行为
Policy
.Handle<DivideByZeroException>()
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(3)
}, (exception, timeSpan) => {
// do something
});
断路器策略
在发生指定次数的异常/故障之后,断开回路
Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1));
发生2次异常之后,断开回路1分钟
Action<Exception, TimeSpan> onBreak = (exception, timespan) => { ... };
Action onReset = () => { ... };
CircuitBreakerPolicy breaker = Policy
.Handle<DivideByZeroException>()
.CircuitBreaker(2, TimeSpan.FromMinutes(1), onBreak, onReset);
发生2次异常之后,断开回路1分钟, 在触发断路时触发onBreak方法,当重置断路器时,触发onReset方法
后备策略
Policy
.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank)
当程序触发异常/故障后,返回一个备用值
Policy
.Handle<Whatever>()
.Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar())
当程序触发异常/故障后,使用一个方法返回一个备用值
Policy
.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>
{
// do something
});
当程序触发异常/故障后,返回一个备用值,并触发一个方法
Policy
.Handle<Whatever>()
.Fallback<UserAvatar>(UserAvatar.Blank, onFallback: (exception, context) =>
{
// do something
});
执行策略
Polly将监控DoSomething方法,如果发生DivideByZeroException异常,就使用重试策略
var policy = Policy
.Handle<DivideByZeroException>()
.Retry();
policy.Execute(() => DoSomething());
向Polly上下文中传递任意值
var policy = Policy
.Handle<DivideByZeroException>()
.Retry(3, (exception, retryCount, context) =>
{
var methodThatRaisedException = context["methodName"];
Log(exception, methodThatRaisedException);
});
policy.Execute(
() => DoSomething(),
new Dictionary<string, object>() {{ "methodName", "some method" }}
);
.NET的弹性及瞬间错误处理库Polly的更多相关文章
- 基于.NET的弹性及瞬间错误处理库Polly
本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及 ...
- NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍
前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...
- 弹性和瞬态故障处理库Polly
介绍 本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略. Polly针对对.NET 4. ...
- 已被.NET基金会认可的弹性和瞬态故障处理库Polly介绍
前言 本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略. Polly针对对.NET 4. ...
- 一点理解之 CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库
@2019-02-14 [小记] CmBacktrace: ARM Cortex-M 系列 MCU 错误追踪库,用来将单片机故障状态寄存器值翻译出来输出至终端上以便排错 CmBacktrace: AR ...
- 使用 Canvas 实现一个类似 Google 的可视化的页面错误反馈库
使用 Canvas 实现一个类似 Google 的可视化的页面错误反馈库 iframe 嵌套 iframe iframe 包含 复制的 HTML 页面 和支持可以拖拽的工具栏 鼠标经过上面,智能识别 ...
- (数据科学学习手札135)tenacity:Python中最强大的错误重试库
本文示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 我们在编写程序尤其是与网络请求相关的程序, ...
- 服务容错处理库Polly使用
服务容错处理库Polly使用 在进入SOA之后,我们的代码从本地方法调用变成了跨机器的通信.任何一个新技术的引入都会为我们解决特定的问题,都会带来一些新的问题.比如网络故障.依赖服务崩溃.超时.服务器 ...
- Hadoop 错误归档库
在hive中操作任意mapreduce相关语句 The size of Container logs revealed the below error: 2015-04-24 11:41:41,858 ...
随机推荐
- kvm 安装操作系统问题
1.出现error processing drive: 解决: --ram 设置到1024 2.分区的时候磁盘文件大小为0 解决:创建虚拟机的时候添加参数ormat=qcow2,size=7,bus= ...
- JavaScript大杂烩12 - 理解Ajax
AJAX缘由 再次谈起这个话题,我深深的记得就在前几年,AJAX被炒的如火如荼,就好像不懂AJAX,就不会Web开发一样.要理解AJAX为什么会出现,就要先了解Web开发面临的问题. 我们先来回忆一下 ...
- SQL PLUS的语句执行Commit
oracle 中有个commit,是用来提交事务的.今天发现sql developer和sql plus的数据查询不一样. 如果我们对数据库进行增删改查,在提交sql语句之后,如果不点击commit, ...
- Intel P4 CPU
1. P4 CPU 结构 奔4处理器是Intel的经典之作,它是采用乱序执行内核的超标量处理器.P4采用的微架构称为 Net Burst,基本结构如下: 奔4处理器微架构被分成了4大部分: (1)存储 ...
- Git的gc功能
http://blog.csdn.net/lihuanshuai/article/details/37345565 Git的底层并没有采用 CVS.SVN 底层所采用的那套增量式文件系统,而是采用一套 ...
- 手把手教你搭建WEB服务器和FTP服务器
注:本次教程的环境是在“Windows 10 PC中远程控制的Windows Server 2012 R2服务器”,你可以自己在自己电脑中安装虚拟机再安装Windows Server 2012 R2服 ...
- apache的php模块讲解以及搭建phpmyadmin管理数据库mysql
1.php php的包名字叫做php-common,其配置文件使用的是ini风格的格式. php的配置文件以分号作为注释,把分号去掉表示启动此片段功能. 在这里我们可以看到php在apache中的模块 ...
- Hive-1.2.1_01_安装部署
前言:该文章是基于 Hadoop2.7.6_01_部署 进行的. 1. Hive基本概念 1.1. 什么是Hive Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库 ...
- golang文件相对路径问题
目录结构: --simple --data --data.json --search --feed.go 具体代码: const dataFile = "../data/data.json& ...
- ConcurrentLinkedQueue源码解读
1.简介 ConcurrentLinkedQueue是JUC中的基于链表的无锁队列实现.本文将解读其源码实现. 2. 论文 ConcurrentLinkedQueue的实现是以Maged M. Mic ...