弹性和瞬态故障处理库Polly
介绍
本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略。 Polly针对对.NET 4.0,.NET 4.5和.NET Standard 1.1以及.NET Core实现,该项目作者现已成为.NET基金会一员,项目一直在不停迭代和更新,项目地址【https://github.com/App-vNext/Polly】,你值得拥有。接下来我们以.NET Framework 4.5来演示它的强大功能。

简单的例子
using System; namespace Polly
{
class Program
{
static void Main(string[] args)
{
// 这个例子展示了当执行的时候如果遇到RedisLockException的异常则会进行重试调用。
var policy = Policy
.Handle<RedisLockException>() // 定义条件
.Retry(); // 定义处理方式 // 执行
policy.Execute(() =>
{
Console.WriteLine("异常之前");
throw new RedisLockException("create lock failed");
Console.WriteLine("异常之后");
}
);
}
} public class RedisLockException : Exception
{
public RedisLockException(string message) : base(message)
{
Console.WriteLine(message);
}
}
}

定义条件
// 单个异常类型
var policy1 = Policy
.Handle<RedisLockException>() // 定义条件
.Retry(); // 定义处理方式 // 限定条件的单个异常 异常和表达式都要符合
var policy2 = Policy
.Handle<RedisLockException>(ex => ex.Message == "wolf")
.Retry(); // 定义处理方式 // 执行
policy2.Execute(() =>
{
Console.WriteLine("异常之前");
throw new RedisLockException("wolf");
Console.WriteLine("异常之后");
}
); // 多个异常类型
Policy
.Handle<HttpRequestException>()
.Or<OperationCanceledException>()
.Retry(); // 定义处理方式 // 限定条件的多个异常
Policy
.Handle<SqlException>(ex => ex.Number == )
.Or<ArgumentException>(ex => ex.ParamName == "example")
.Retry(); // 定义处理方式 // Inner Exception 异常里面的异常类型
Policy
.HandleInner<HttpRequestException>()
.OrInner<OperationCanceledException>(ex => ex.CancellationToken != new System.Threading.CancellationToken())
.Retry(); // 定义处理方式
以及用返回结果来限定
// 返回结果加限定条件
Policy
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.NotFound) // 处理多个返回结果
Policy
.HandleResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.InternalServerError)
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.BadGateway) // 处理元类型结果 (用.Equals)
Policy
.HandleResult<HttpStatusCode>(HttpStatusCode.InternalServerError)
.OrResult<HttpStatusCode>(HttpStatusCode.BadGateway) // 在一个policy里面同时处理异常和返回结果。
HttpStatusCode[] httpStatusCodesWorthRetrying = {
HttpStatusCode.RequestTimeout, //
HttpStatusCode.InternalServerError, //
HttpStatusCode.BadGateway, //
HttpStatusCode.ServiceUnavailable, //
HttpStatusCode.GatewayTimeout //
};
HttpResponseMessage result = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
.RetryAsync(...)
.ExecuteAsync( /* some Func<Task<HttpResponseMessage>> */ )
重试策略(Retry)
重试策略针对的前置条件是短暂的故障延迟且在短暂的延迟之后能够自我纠正。允许我们做的是能够自动配置重试机制。
按次数重试
using System; namespace Polly
{
class Program
{
static void Main(string[] args)
{
// 重试1次
Policy
.Handle<RedisLockException>()
.Retry().Execute(() => { throw new RedisLockException(""); }); //// 重试3(N)次
Policy
.Handle<RedisLockException>()
.Retry().Execute(() => { throw new RedisLockException(""); }); ; //// 重试多次,加上重试时的action参数
Policy
.Handle<RedisLockException>()
.Retry(, (exception, retryCount) =>
{
Console.WriteLine(exception.Message);
Console.WriteLine(retryCount);
}).Execute(() => { throw new RedisLockException(""); });
}
} public class RedisLockException : Exception
{
public RedisLockException(string message) : base(message)
{
Console.WriteLine(message);
}
}
}
不断重试
using System; namespace Polly
{
class Program
{
static void Main(string[] args)
{
// 不断重试,直到成功
Policy
.Handle<RedisLockException>()
.RetryForever().Execute(() => { }); // 不断重试,带action参数在每次重试的时候执行
Policy
.Handle<RedisLockException>()
.RetryForever(exception =>
{
// do something
}).Execute(() => { });
}
} public class RedisLockException : Exception
{
public RedisLockException(string message) : base(message)
{
Console.WriteLine(message);
}
}
}
等待之后重试
using System; namespace Polly
{
class Program
{
static void Main(string[] args)
{
// 重试3次,分别等待10、20、30秒。
Policy
.Handle<RedisLockException>()
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(),
TimeSpan.FromSeconds(),
TimeSpan.FromSeconds()
}).Execute(() => { throw new RedisLockException(""); });
}
} public class RedisLockException : Exception
{
public RedisLockException(string message) : base(message)
{
Console.WriteLine(message);
}
}
}
熔断
熔断也可以被作为当遇到某种错误场景下的一个操作。以下代码展示了当发生2次RedisLockException的异常的时候则会熔断1分钟,该操作后续如果继续尝试执行则会直接返回错误 。
Policy
.Handle<SomeExceptionType>()
.CircuitBreaker(, TimeSpan.FromMinutes());
回退(Fallback)
操作仍然会失败,也就是说当发生这样的事情时我们打算做什么。也就是说定义失败返回操作。
class Program
{
static void Main(string[] args)
{
try
{
var fallBackPolicy =
Policy<string>
.Handle<DivideByZeroException>()
.Fallback("执行失败,返回Fallback");
//运行异常时,设置默认值
var fallBack = fallBackPolicy.Execute(Compute);
Console.WriteLine(fallBack);
}
catch (DivideByZeroException e)
{
Console.WriteLine($"Excuted Failed,Message: ({e.Message})");
}
Console.Read();
} static string Compute()
{
var a = ;
a = / a;
return "无异常时函数";
}
}
弹性和瞬态故障处理库Polly的更多相关文章
- 已被.NET基金会认可的弹性和瞬态故障处理库Polly介绍
前言 本节我们来介绍一款强大的库Polly,Polly是一种.NET弹性和瞬态故障处理库,允许我们以非常顺畅和线程安全的方式来执诸如行重试,断路,超时,故障恢复等策略. Polly针对对.NET 4. ...
- NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍
前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...
- Polly一种.NET弹性和瞬态故障处理库(重试策略、断路器、超时、隔板隔离、缓存、回退、策略包装)
下载地址:https://github.com/App-vNext/Polly 该库实现了七种恢复策略. 重试策略(Retry) 重试策略针对的前置条件是短暂的故障延迟且在短暂的延迟之后能够自我纠正. ...
- 【微服务No.2】polly微服务故障处理库
熔断.降级: 熔断:熔断就是我们常说的“保险丝”,意为当服务出现某些状况时,切断服务,从而防止应用程序不断地常识执行可能会失败的操作造成系统的“雪崩”,或者大量的超时等待导致系统卡死等情况,很多地方也 ...
- .NET的弹性及瞬间错误处理库Polly
原文:.NET的弹性及瞬间错误处理库Polly 本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET ...
- 服务容错处理库Polly使用
服务容错处理库Polly使用 在进入SOA之后,我们的代码从本地方法调用变成了跨机器的通信.任何一个新技术的引入都会为我们解决特定的问题,都会带来一些新的问题.比如网络故障.依赖服务崩溃.超时.服务器 ...
- 基于.NET的弹性及瞬间错误处理库Polly
本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及 ...
- ASP VNext 开源服务容错处理库Polly使用文档
在进入SOA之后,我们的代码从本地方法调用变成了跨机器的通信.任何一个新技术的引入都会为我们解决特定的问题,都会带来一些新的问题.比如网络故障.依赖服务崩溃.超时.服务器内存与CPU等其它问题.正是因 ...
- 容错处理库Polly使用文档
Design For Failure1. 一个依赖服务的故障不会严重破坏用户的体验.2. 系统能自动或半自动处理故障,具备自我恢复能力. 以下是一些经验的服务容错模式 超时与重试(Timeout an ...
随机推荐
- MySQL没有备份怎么恢复被drop的表(利用undrop-for-innodb)
介绍: 也许大家都难以理解,这么重要的数据为啥不备份(或者备份不可用)?而且还任性的drop table了.显然有备份是最好的,但是它们并不总是可用的.这种情况令人恐惧,但并非毫无希望.在许多 ...
- 对比Dijakstra和优先队列式分支限界
Dijakstra和分支限界都是基于广度优先搜索,如果说两者都是生成一棵树,那Dijakstra总是找距离树根最近的(属于贪心算法),优先队列式分支限界是在层遍历整棵搜索树的同时剪去达不到最优的树枝. ...
- hibernate框架学习之数据抓取(加载)策略
Hibernate获取数据方式 lHibernate提供了多种方式获取数据 •load方法获取数据 •get方法获取数据 •Query/ Criteria对象获取数据 lHibernate获取的数据分 ...
- NOI2019 SX 模拟赛 no.5
Mas 的童年 题目描述:不知道传送门有没有用? 反正就是对于每个前缀序列求一个断点,使得断点左右两个区间的 分别的异或和 的和最大 分析 jzoj 原题? 但是我 TM 代码没存账号也过期了啊! 然 ...
- <TCP/IP>Internet地址结构回顾
本章介绍了Internet中使用的网络层地址,又称IP地址. 要想在网上冲浪,一个设备至少要有一个IP地址(PS:我用赛风FQ的时候,居然自动更换了IP地址,顿时感觉很神奇但是不知道为什么) ***成 ...
- $Django 多对多-自定义第三张表 基于双下划线的跨表查询(补充)
自定义第三张表的好处:可以定义多个字段, 缺点:查询不方便(有方法解决) 1.第三张表设置外键,联合唯一(查询不方便) class Books(models.Model): name=models.C ...
- freeswitch反注册记录
应用情景: 使用阿里服务器,落地使用本地的模拟线路(O口网关). 1.FreeSWITCH 服务器开一个账号,比如 5000 internal , O口 SIP设置页面按照网关注册 5000 的账号信 ...
- [转载]RabbitMQ消息可靠性分析
有很多人问过我这么一类问题:RabbitMQ如何确保消息可靠?很多时候,笔者的回答都是:说来话长的事情何来长话短说.的确,要确保消息可靠不只是单单几句就能够叙述明白的,包括Kafka也是如此.可靠并不 ...
- 【原创】运维基础之Docker(6)性能
The general result is that Docker is nearly identical to Native performance and faster than KVM in e ...
- CentOS7.5从零安装Python3.6.6
ps:环境如标题 安装可能需要的依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlit ...