7

如何更简单的使用Polly

 3 years ago
source link: http://www.cnblogs.com/fs7744/p/14129076.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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


Recommend

  • 18
    • netflix.github.io 6 years ago
    • Cache

    Polly.JS

    Standalone, framework-agnostic JavaScript library that enables recording, replaying, and stubbing HTTP interactions.

  • 37

    In the previous post in this series , I introduced the concept of outgoing middleware u...

  • 27

    熔断降级是一个非常重要的概念,我们先说一下什么是熔断降级,咱们都知道服务发现,一个有问题的服务器没来得急注销过一会就崩溃掉了,那么我们的请求就有可能访问一个已经崩溃的服务器,那么就会请求失败,因为已经

  • 34

    Nowadays, most mobile and desktop applications depend on external services for their optimal operations. Whether it is for the consumption of dat...

  • 8
    • scottdorman.blog 3 years ago
    • Cache

    Database Resiliency with Polly

    Database Resiliency with PollyHandling errors is important to make your application more reliable. We all understand the importance of Defensive programming (I

  • 10
    • www.aligneddev.net 3 years ago
    • Cache

    Polly Presentation and links

    Polly Presentation and Links I had the honor of going to NDC Minneapolis in 2019. One of the many presentations I attended was about P...

  • 10
    • www.stevefenton.co.uk 3 years ago
    • Cache

    Microsoft Teams – Ask Questions with Polly

    Microsoft Teams has a growing collection of apps that can be used to enhance your calls and chats. One of these is Polly, which lets you run highly configurable polls within your chats.Installing PollyTo install Polly, click o...

  • 9

    ASP.NET Core gRPC 集成 Polly 实现优雅重试2021-06-0726 29 min.在上一篇 博客 中,我们一起探索和实现了gRPC的健康检查。从服务治理的角度来看,健康检查保证的...

  • 10

    .NET Polly CircuitBreakerPolicy-黑暗執行緒昨天提到 Polly 的 Circuit Breaker,研究後發現比想像複雜,寫篇筆記備忘。 Circuit Breaker 概念類似電路系統的熔斷開關或保險絲,能...

  • 6
    • Github github.com 2 years ago
    • Cache

    Issues · App-vNext/Polly · GitHub

    Issues · App-vNext/Polly · GitHub Clear current search query, filters, and sorts Author Label...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK