c# 如何更简单的使用Polly
程序员文章站
2022-03-06 11:01:02
polly是一个c#实现的弹性瞬时错误处理库它可以帮助我们做一些容错模式处理,比如: 超时与重试(timeout and retry) 熔断器(circuit breaker) 舱壁隔离(bul...
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
2.编写 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)); } }
3.考虑到 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)); } }
4.我们来做个测试吧
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
以上就是c# 如何更简单的使用polly的详细内容,更多关于c# 使用polly的资料请关注其它相关文章!