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

最新文章

  1. bzoj 1305 dance跳舞
  2. 《C与指针》第八章练习
  3. Visual Studio 2012中文旗舰版(序列号和下载地址)
  4. Python核心编程笔记(类)
  5. html插入链接
  6. UVa 11400 Lighting System Design【DP】
  7. 8个应该去逛逛JQuery的学习网站
  8. 框架搭建资源 (一) V(视图)C(控制)模式
  9. Altium Designer 快速修改板子形状为Keep-out layer大小
  10. 2019-04-26-day041-数据库的索引
  11. 关于tpg例程的仿真
  12. load 过高分析办法
  13. Quartz.Net分布式任务管理平台
  14. 设计模式---策略模式Strategy(对象行为型)
  15. PHP html mysql js 乱码问题,UTF-8(乱码)
  16. Win10系列:VC++ Direct3D图形绘制1
  17. Linux常用命令--文件操作、权限设置
  18. java SE :标准输入/输出
  19. oozie4.3.0的安装与配置 + hadoop2.7.3
  20. C#集合之队列

热门文章

  1. Python_获取cookie
  2. Java项目读取resources资源文件路径那点事
  3. python菜鸟教程学习5: python运算符
  4. C#设计模式-外观模式(Facade Pattern)
  5. ①SpringCloud 实战:引入Eureka组件,完善服务治理
  6. java的常用定时任务的几种方式
  7. leetcode151. 翻转字符串里的单词
  8. python接口测试2-开发WEB接口
  9. python—数据类型和变量
  10. js中定时器调用函数时为什么会有引号