Polly 重试策略

工作原理

Polly重试工作原理

Retry

基本重试:

public static void Retry()
{
    var random = new Random();

    // Policy<> 泛型定义返回值类型, 如若不需要返回值, 可直接使用 Policy
    var obj = Policy<object>

        // Handle<> 可指定需要处理的异常类型
        .Handle<Exception>()

        //也可以使用重载对Exception 进行再次过滤
        //.Handle<Exception>(e => e is NotSupportedException)                

        .Retry(3, (res, i, c) =>
               {
                   //当委托的代码块执行失败时会进入此 Action, 
                   //这里可以对抛出的异常进行日志或其他处理
                   Console.WriteLine($"retry {i}th times, ex: {res.Exception?.Message}");
               })
        .Execute(() =>
                 {
                      var val = random.Next(0, 100);
                    switch (val % 3)
                    {
                        case 0:
                            return "Success";
                        default:
                            throw new Exception($"random val: {val}");
                    }
                 });
    Console.WriteLine(obj);
}

输出:

重试一次成功:

retry_1

重试两次成功:

retry_2

重试三次均失败:

retry_3

可以看到,再超过重试次数的时候, 若程序还是异常,则抛出异常。

RetryForever

成功前一直重试:

public static void RetryForever()
{
    var random = new Random();

    // Policy<> 泛型定义返回值类型, 如若不需要返回值, 可直接使用 Policy
    var obj = Policy<object>

        // Handle<> 可指定需要处理的异常类型
        .Handle<Exception>()

        //也可以使用重载对Exception 进行再次过滤
        //.Handle<Exception>(e => e is NotSupportedException)                

        .RetryForever((res, i, c) =>
                      {
                          //当委托的代码块执行失败时会进入此 Action, 
                          //这里可以对抛出的异常进行日志或其他处理
                          Console.WriteLine($"retry {i}th times, ex: {res.Exception?.Message}");
                      })
        .Execute(() =>
                 {
                     var val = random.Next(0, 100);
                     switch (val % 999)
                     {
                         case 0:
                             return $"Success, val: {val}";
                         default:
                             throw new Exception($"random val: {val}");
                     }
                 });

    Console.WriteLine(obj);
}

输出:

retry_forever_1

case 0: 这个分支去掉, 任务将变为不可能成功,会发现一直输出重试。

WaitAndRetry

程序异常后做短暂延迟再次重试:

.WaitAndRetry(5, 
                
                // 设置 Sleep Duration Provider 来提供延迟时间
                retryTimes => TimeSpan.FromSeconds(Math.Pow(2, retryTimes)),

                (res, delay, times, context) =>
                {
                    //当委托的代码块执行失败时会进入此 Action, 
                    //这里可以对抛出的异常进行日志或其他处理
                    Console.WriteLine($"retry {times}th times, sleep: {delay.TotalSeconds}s, ex: {res.Exception?.Message}");
                })

可以看到我们在 WaitAndRetry 方法中提供了延迟方式: retryTimes => TimeSpan.FromSeconds(Math.Pow(2, retryTimes)),, 这是一种比较典型的延迟方式,叫做 指数退避。

输出:

retry_wait_1

WaitAndRetryForever

.WaitAndRetryForever(

                // 设置 Sleep Duration Provider 来提供延迟时间
                (retryTimes, res, context) => TimeSpan.FromSeconds(Math.Pow(2, retryTimes)),

                (res, times, delay, context) =>
                {
                    //当委托的代码块执行失败时会进入此 Action, 
                    //这里可以对抛出的异常进行日志或其他处理
                    Console.WriteLine($"retry {times}th times, sleep: {delay.TotalSeconds}s, ex: {res.Exception?.Message}");
                })

仅仅与 WaitAndRetrySleepDurationProvider 的参数有点不同

小结

此篇大体概括了 Polly 重试的几种方式, 当然 Polly Retry 还有很多重载, 但作用都是围绕 程序异常时进行自我调整再重试 为中心。

猜你喜欢

转载自www.cnblogs.com/rajesh/p/10773564.html