如何更简单的使用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方式我之前 ...
随机推荐
- mysql之sql语句逻辑执行顺序
1. (1)from先执行,from执行后就会将所有表(多个表时和单表所有的表)数据加载到内存中了 (2)ON执行,得到连接表用的连接条件. (3)JOIN执行,根据ON的连接条件,将from加载的所 ...
- 用FL Studio来给电子音乐混音的方法
FL Studio也算是音乐人用的比较多的编曲.混音软件了,FL Studio的一大的特色就是电子音乐的制作.尤其是对混音的操作,混音是电音制作过程中一个非常重要的环节,非常重要. 混音是什么?混音的 ...
- FL Studio录制面板知识讲解
FL Studio录制面板可以设置与录制有关的选项,它还有一个用来设置音符对齐的全局吸附选择器.刚接触水果这款音乐制作软件的同学通常不是很清楚这里的知识的,下面小编就给大家讲解一下. 1.首先,我们来 ...
- 清理工具CleanMyMac如何帮助用户清空DNS缓存
什么是DNS缓存?这个缓存有什么危害?相信大家平时使用浏览器时,有时候会遇到一个很奇怪的问题,就是Mac打开许多网站如百度网站,都是可以访问的,但是在打开某个特定网站时,却发现浏览器提示检测不到网络连 ...
- 为什么Java不允许创建范型数组
问题示例 List<Integer>[] intListArr = new ArrayList<Integer>[8]; // 编译时报错 能看到这么看似没啥问题的一个简单语句 ...
- leetcode187. 重复的DNA序列
所有 DNA 都由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助.编写一个函数 ...
- ClassLoader分类
对于类装载器而言一共有三种, 1分别是加载rt包下的Bootstrap加载器,是用C++写的,是在java最早发布的时候写的,用于加载那些最初的类. 2然后java在发展过程中又要发布新的jdk,所以 ...
- 学习django笔记一:在urls.py中导入sign应用views文件的问题
>python-admin startproject guest #创建guest项目 >python3 manage.py startapp sign #在guest项目中创建 ...
- Jmeter如何监测被测服务器资源
前言 Jmeter自身不支持对服务器的监控,需要安装第三方插件进行扩展. 下载插件 jmeter添加插件步骤,选项-PluginManager 勾选上PerfMon选项,点击右下角的Apply-按钮 ...
- 《高并发下的.NET》第2季 - 《memcached连接暴增案》第1集:问题表现
在<.NET 5.0 背锅案>第7集-大结局之后,园子和 .NET 继续过上了幸福生活...剧情很美好,现实很残酷...现实是旧案刚结,新案立至,而且新案与旧案有关联,被迫继续拍剧,并对该 ...