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吧

  1. 安装 AOP 框架

    自己写多累呀,用现成的多好呀
dotnet add package Norns.Urd
  1. 编写 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));
}
}
  1. 考虑到 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));
}
}
  1. 我们来做个测试吧
    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的更多相关文章

  1. 【热门技术】EventBus 3.0,让事件订阅更简单,从此告别组件消息传递烦恼~

    一.写在前面 还在为时间接收而烦恼吗?还在为各种组件间的消息传递烦恼吗?EventBus 3.0,专注于android的发布.订阅事件总线,让各组件间的消息传递更简单!完美替代Intent,Handl ...

  2. PostCSS一种更优雅、更简单的书写CSS方式

    Sass团队创建了Compass大大提升CSSer的工作效率,你无需考虑各种浏览器前缀兼,只需要按官方文档的书写方式去写,会得到加上浏览器前缀的代码,如下: .row { @include displ ...

  3. 【转】【C#】C# 5.0 新特性——Async和Await使异步编程更简单

    一.引言 在之前的C#基础知识系列文章中只介绍了从C#1.0到C#4.0中主要的特性,然而.NET 4.5 的推出,对于C#又有了新特性的增加--就是C#5.0中async和await两个关键字,这两 ...

  4. [转]九个Console命令,让js调试更简单

    转自:九个Console命令,让js调试更简单 一.显示信息的命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <!DOCTYPE html> <html ...

  5. gulp:更简单的自动化构建工具

    目前最流行的两种使用JavaScript开发的构建工具是Grunt和Gulp.为什么使用gulp?因为Gulp更简单.Grunt任务拥有大量的配置,会引用大量你实际上并不需要的对象属性,但是Gulp里 ...

  6. 使用hessian开发WebService,轻量级,更简单、快捷

    Hessian是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能. 相比WebService,Hessian更简单.快捷.采用的是二进制RPC协议,因为采用的是二进制协 ...

  7. Rsession让Java调用R更简单

    Rsession让Java调用R更简单 R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大. R语言作为统计学一门语言,一直在小众领域闪耀着光芒. ...

  8. spring 第一篇(1-1):让java开发变得更简单(下)

    切面(aspects)应用 DI能够让你的软件组件间保持松耦合,而面向切面编程(AOP)能够让你捕获到在整个应用中可重用的组件功能.在软件系统中,AOP通常被定义为提升关注点分离的一个技术.系统由很多 ...

  9. spring 第一篇(1-1):让java开发变得更简单(下)转

    spring 第一篇(1-1):让java开发变得更简单(下) 这个波主虽然只发了几篇,但是写的很好 上面一篇文章写的很好,其中提及到了Spring的jdbcTemplate,templet方式我之前 ...

随机推荐

  1. http://www.etymon.cn/yingyucigen/3093.html

    import requests import lxml.etree as etree import xml.etree.ElementTree as ET # 详情页 # 3093-148 # htt ...

  2. App安全常见漏洞修复建议

    ios开发对自己的app做一系列的环境检测 检测Cydia是否安装 检测app是否可以编辑系统文件 检测系统是否包含可疑的文件 检测是否有可疑的app安装如:FakeCarrier, Icy, etc ...

  3. 微信支付回调 敏感信息解密 v3 php

    今天博主用了一波微信的v3版本的支付,支付成功后发现回调跟v2的完全不一样,于是去看了了一波v3的文档,发现信息是经过加密的,需要解密才能获取的到 但是最悲催的是文档上没写怎么解密的,经过了一下午的百 ...

  4. 使用iOS 设备管理器 iMazing导出苹果设备中的录音文件

    iMazing是一款功能强大的苹果设备管理软件,能为用户提供便捷的录音文件导出功能.用户可以直接将录音文件从苹果设备中导出,接下来,就让小编为大家演示一下如何操作吧. 图1:iMazing界面 1.打 ...

  5. 2019年第十届蓝桥杯【C++省赛B组】D、E、G、H、I题解

    这场有几道题目思路,在之前比赛中遇到过 D. 数的分解 #枚举 题意 将\(2019\)分解成\(3\)个各不相同的正整数之和,并且每个正整数都不包含数字\(2\)和\(4\),一共有多少种分解方法? ...

  6. Codeforces Round #670 (Div. 2) D. Three Sequences 题解(差分+思维+构造)

    题目链接 题目大意 给你一个长为n的数组a,要你构造一个非严格单调上升的数组b和一个非严格单调下降的数组c,使得\(b_i+c_i=a_i\) 要你使这两个数组b,c中最大的元素最小,还有q次修改(q ...

  7. CentOS下的IPMI尝试

    1.载入支持 ipmi 功能的系统模块 modprobe ipmi_msghandler modprobe ipmi_devintf modprobe ipmi_poweroff modprobe i ...

  8. Unity全局调用非静态函数

    Unity全局调用非静态函数 情形 大概就是做游戏的时候想做一个给玩家展示信息的东西,比如玩家按了不该按的键提醒一下之类的.这个脚本倒是很简单,找个Text组件往上面加字就行了.问题在于这个脚本游戏中 ...

  9. Splay树求第k大模板

    今天上午借着休息日得机会手撸了一下模板,终于对着模板调出来了.prev和next占用了std namespace里面的东西,然后报警我上次给关了所以.....就花了3个小时吧. inline加不加无所 ...

  10. zookeeper基础笔记

    一.安装 1.安装jdk 2.安装Zookeeper 3.单机模式(stand-alone):安装目录/conf   复制 zoo_sample.cfg 并粘贴到当前目录下,命名zoo.cfg. 二. ...