如何更简单的使用Polly
Polly 弹性瞬时错误处理库
Polly是一个C#实现的弹性瞬时错误处理库
它可以帮助我们做一些容错模式处理,比如:
- 超时与重试(Timeout and Retry)
- 熔断器(Circuit Breaker)
- 舱壁隔离(Bulkhead Isolation)
- 回退(Fallback)
使用也是非常简单的,比如:
// Retry multiple times, calling an action on each retry
// with the current exception and retry count
Policy
.Handle<SomeExceptionType>()
.Retry(3, onRetry: (exception, retryCount) =>
{
// Add logic to be executed before each retry, such as logging
});
但是每个地方我们都得这样写,个人还是不喜,
那么怎么简化呢?
当然是使用 Norns.Urd 这些AOP框架封装我们常用的东西做成 Attribute 啦
如何实现简化呢?
我们来尝试将 Retry功能 做成 RetryAttribute吧
- 安装 AOP 框架
自己写多累呀,用现成的多好呀
dotnet add package Norns.Urd
- 编写 Retry InterceptorAttribute
public class RetryAttribute : AbstractInterceptorAttribute
{
private readonly int retryCount;
public RetryAttribute(int retryCount)
{
this.retryCount = retryCount;
}
public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
await Policy.Handle<Exception>()
.RetryAsync(retryCount)
.ExecuteAsync(() => next(context));
}
}
- 考虑到 async 和 sync 在Polly 有差异,那么我们兼容一下吧
public class RetryAttribute : AbstractInterceptorAttribute
{
private readonly int retryCount;
public RetryAttribute(int retryCount)
{
this.retryCount = retryCount;
}
public override void Invoke(AspectContext context, AspectDelegate next)
{
Policy.Handle<Exception>()
.Retry(retryCount)
.Execute(() => next(context));
}
public override async Task InvokeAsync(AspectContext context, AsyncAspectDelegate next)
{
await Policy.Handle<Exception>()
.RetryAsync(retryCount)
.ExecuteAsync(() => next(context));
}
}
- 我们来做个测试吧
public class RetryTest
{
public class DoRetryTest
{
public int Count { get; set; }
[Retry(2)] // 使用 Retry
public virtual void Do()
{
if (Count < 50)
{
Count++; // 每调用一次就加1
throw new FieldAccessException();
}
}
}
public DoRetryTest Mock()
{
return new ServiceCollection()
.AddTransient<DoRetryTest>()
.ConfigureAop()
.BuildServiceProvider()
.GetRequiredService<DoRetryTest>();
}
[Fact]
public void RetryWhenSync()
{
var sut = Mock();
Assert.Throws<FieldAccessException>(() => sut.Do());
Assert.Equal(3, sut.Count); //我们期望调用总共 3 次
}
}
是的,就是这样,我们可以在任何地方使用 RetryAttribute
当然,一些常见的方法已经封装在了 Norns.Urd.Extensions.Polly
这里通过Norns.Urd将Polly的各种功能集成为更加方便使用的功能
如何启用 Norns.Urd + Polly, 只需使用EnablePolly()
如:
new ServiceCollection()
.AddTransient<DoTimeoutTest>()
.ConfigureAop(i => i.EnablePolly())
TimeoutAttribute
[Timeout(seconds: 1)] // timeout 1 seconds, when timeout will throw TimeoutRejectedException
double Wait(double seconds);
[Timeout(timeSpan: "00:00:00.100")] // timeout 100 milliseconds, only work on async method when no CancellationToken
async Task<double> WaitAsync(double seconds, CancellationToken cancellationToken = default);
[Timeout(timeSpan: "00:00:01")] // timeout 1 seconds, but no work on async method when no CancellationToken
async Task<double> NoCancellationTokenWaitAsync(double seconds);
RetryAttribute
[Retry(retryCount: 2, ExceptionType = typeof(AccessViolationException))] // retry 2 times when if throw Exception
void Do()
CircuitBreakerAttribute
[CircuitBreaker(exceptionsAllowedBeforeBreaking: 3, durationOfBreak: "00:00:01")]
//or
[AdvancedCircuitBreaker(failureThreshold: 0.1, samplingDuration: "00:00:01", minimumThroughput: 3, durationOfBreak: "00:00:01")]
void Do()
BulkheadAttribute
[Bulkhead(maxParallelization: 5, maxQueuingActions: 10)]
void Do()
有关 Norns.Urd, 大家可以查看 https://fs7744.github.io/Norns.Urd/zh-cn/index.html
如何更简单的使用Polly的更多相关文章
- 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~
一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...
- PostCSS一种更优雅、更简单的书写CSS方式
Sass团队创建了Compass大大提升CSSer的工作效率,你无需考虑各种浏览器前缀兼,只需要按官方文档的书写方式去写,会得到加上浏览器前缀的代码,如下: .row { @include displ ...
- 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单
一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...
- [转]九个Console命令,让js调试更简单
转自:九个Console命令,让js调试更简单 一.显示信息的命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html> <html ...
- gulp:更简单的自动化构建工具
目前最流行的两种使用JavaScript开发的构建工具是Grunt和Gulp.为什么使用gulp?因为Gulp更简单.Grunt任务拥有大量的配置,会引用大量你实际上并不需要的对象属性,但是Gulp里 ...
- 使用hessian开发WebService,轻量级,更简单、快捷
Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...
- Rsession让Java调用R更简单
Rsession让Java调用R更简单 R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒. ...
- spring 第一篇(1-1):让java开发变得更简单(下)
切面(aspects)应用 DI能够让你的软件组件间保持松耦合,而面向切面编程(AOP)能够让你捕获到在整个应用中可重用的组件功能.在软件系统中,AOP通常被定义为提升关注点分离的一个技术.系统由很多 ...
- spring 第一篇(1-1):让java开发变得更简单(下)转
spring 第一篇(1-1):让java开发变得更简单(下) 这个波主虽然只发了几篇,但是写的很好 上面一篇文章写的很好,其中提及到了Spring的jdbcTemplate,templet方式我之前 ...
随机推荐
- java 关于 a==null 和 null==a, a.equals("123") 和“123”.equals(a)
一: a==null 和 null==a 实验 所以 a==null 和 null==a 没区别 二: a.equals("123") 和"123".equal ...
- Spring接口
FactoryBean接口 Spring中有两种类型的Bean:一种是普通的JavaBean:另一种就是工厂Bean(FactoryBean),这两种Bean都受Spring的IoC容器管理. Fac ...
- Linux(CentOS6.8)配置Docker
Centos6.8 1.查看自己的内核 [1].uname [root@host79 ~]# uname -r 2.6.32-642.el6.x86_64 [2].查看CentOS版本信息 CentO ...
- UML中常见的类关系你了解吗?
最近老大给我设计了一个微信扫码登录的通过工具包流程图,设计过程中使用了模板模式.面向接口编程等设计思路,让我很享受整个过程:下来我就接触了一下Java的设计模式,很是懵懂,听说这也是要靠经验来喂,才能 ...
- 分布式监控系统之Zabbix 使用SNMP、JMX信道采集数据
前文我们了解了zabbix的被动.主动以及web监控相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14024212.html:今天我们来了解下zabb ...
- 简单实用的Boom 3D基础入门教程分享
Boom 3D可以很大限度的弥补声音设备或是环境的不足,满足您更加高级的声学体验.Boom 3D用简单明了的方式帮助您设计声音,即使您不是专业的声音编辑,也可以达到专业相似的效果. 打开Boom 3D ...
- jquery删除文件
1 <div class="panel panel-default"> 2 <div class="panel-body"> 3 < ...
- 基于Kubernetes和OpenKruise的可变基础设施实践
本文首发在OPPO互联网公众号,欢迎点击转载 https://mp.weixin.qq.com/s/hRvZz_bZfchmP0tkF6M2OA 对于可变基础设施的思考 kubernetes中的可变与 ...
- CSS3 学习笔记(上)
一.CSS简介 CSS(Cascading Style Sheets)层叠样式表.其中,样式定义为如何显示HTML元素,它通常储存在样式表,将样式添加到HTML中,能够解决内容与表现分离的问题.由于网 ...
- SpringCloud 源码系列(2)—— 注册中心 Eureka(中)
五.服务注册 1.实例信息注册器初始化 服务注册的代码位置不容易发现,我们看 DiscoveryClient 初始化调度任务的这个方法,这段代码会去初始化一个实例信息复制器 InstanceInfoR ...