.Net Core 使用弹性和瞬态故障处理库Polly

1、Polly介绍

  1、Polly是一个基于.NET的弹性及瞬态故障处理库,允许开发人员以顺畅及线程安全的方式执行重试(Retry)、断路(Circuit Breaker)、超时(Timeout)、隔离(Bulkhead Isolation)和回退策略(Fallback ),polly的介绍中有个很关键的词是瞬态故障,这个词也很好的诠释了Polly使用的一个背景.瞬态故障,就是指我们的程序在运行当中可能会发生故障, 这些故障包含程序运行中的异常、返回结果不符等。弹性是指Polly在应对这些故障时具有灵活性,且其提供的策略也可以很灵活的组合在一起使用。

2、Polly的使用

  1、在Nuget中下载Polly安装包,安装成功即可使用

  2、我对此Polly稍微封装成个类供大家学习

public class PollyEngin
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TException">指定需要重试异常的类型</typeparam>
        /// <typeparam name="TResult">指定返回值类型</typeparam>
        /// <param name="action">需要执行的Action</param>
        /// <param name="timeSpans">执行的次数以及次数之间的间隔时间</param>
        /// <returns></returns>
        public static async Task<TResult> PollyResultWaitAndRetryAsync<TException, TResult>(Func<Task<TResult>> action, params TimeSpan[] timeSpans) where TException : Exception
        {
            var policy = Policy
            .Handle<TException>()
            .WaitAndRetryAsync(timeSpans, (e, tiempo, intento, contexto) =>
            {
                Console.WriteLine($"{action.Method.Name}执行失败,{intento:00} (调用秒数: {tiempo.Seconds} 秒),异常来自:{e.ToString()}");
            });
            return await policy.ExecuteAsync(action);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TException">指定需要重试异常的类型</typeparam>
        /// <param name="action">需要执行的Action</param>
        /// <param name="timeSpans">执行的次数以及次数之间的间隔时间</param>
        /// <returns></returns>
        public static async Task PollyResultWaitAndRetryAsync<TException>(Func<Task> action, params TimeSpan[] timeSpans) where TException : Exception
        {
            var policy = Policy
            .Handle<TException>()
            .WaitAndRetryAsync(timeSpans, (e, tiempo, intento, contexto) =>
            {
                Console.WriteLine($"{action.Method.Name}执行失败,{intento:00} (调用秒数: {tiempo.Seconds} 秒),异常来自:{e.ToString()}");
            });
            await policy.ExecuteAsync(action);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TException">指定需要重试异常的类型</typeparam>
        /// <param name="action">需要执行的Action</param>
        /// <param name="keyValues">需要执行的Action入参参数,格式使用key values</param>
        /// <param name="timeSpans">执行的次数以及次数之间的间隔时间</param>
        /// <returns></returns>
        public static async Task PollyResultWaitAndRetryAsync<TException>(Func<Context, Task> action, Context keyValues, params TimeSpan[] timeSpans) where TException : Exception
        {
            var policy = Policy
            .Handle<TException>()
            .WaitAndRetryAsync(timeSpans, (e, tiempo, intento, contexto) =>
            {
                Console.WriteLine($"{action.Method.Name}执行失败,{intento:00} (调用秒数: {tiempo.Seconds} 秒),异常来自:{e.ToString()}");
            });
            await policy.ExecuteAsync(action, keyValues);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TException">指定需要重试异常的类型</typeparam>
        /// <typeparam name="TResult">指定返回值类型</typeparam>
        /// <param name="action">需要执行的Action</param>
        /// <param name="keyValues">格式使用key values</param>
        /// <param name="timeSpans">执行的次数以及次数之间的间隔时间</param>
        /// <returns></returns>
        public static async Task PollyResultWaitAndRetryAsync<TException, TResult>(Func<Context, Task<TResult>> action, Context keyValues, params TimeSpan[] timeSpans) where TException : Exception
        {
            var policy = Policy
            .Handle<TException>()
            .WaitAndRetryAsync(timeSpans, (e, tiempo, intento, contexto) =>
            {
                Console.WriteLine($"{action.Method.Name}执行失败,{intento:00} (调用秒数: {tiempo.Seconds} 秒),异常来自:{e.ToString()}");
                if (keyValues.TryGetValue("retryCount", out object count))
                    keyValues.Remove("retryCount");
                keyValues.Add("retryCount", intento);
            });
            await policy.ExecuteAsync(action, keyValues);
        }
    }

  3、PollyEngin使用方式

  

class Program
    {
        static void Main(string[] args)
        {
            var result = PollyEngin.PollyResultWaitAndRetryAsync<Exception>(task, TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(10));
            Console.ReadLine();
        }
        public async static Task task()
        {
            Console.WriteLine("任务开始");
            await Task.Delay(TimeSpan.FromSeconds(1));
            Console.WriteLine("任务结束");
            throw new Exception();
        }

    }

结果展示:

 

  

 

posted @ 2021-04-21 16:06  Dark丶潇洒哥  阅读(297)  评论(0编辑  收藏  举报