.NET熔断之Polly

1.

Net Core 中有一个被.Net 基金会认可的库 Polly,可以用来简化熔断降级的处理。主要功能:重试(Retry);断路器(Circuit-breaker);超时检测(Timeout);缓存(Cache);降级(FallBack);

官网:https://github.com/App-vNext/Polly

介绍文章:https://www.cnblogs.com/CreateMyself/p/7589397.html

Nuget安装指令:Install-Package Polly -Version 6.1.2

 

using System.Threading;
using System.Threading.Tasks;
using Daocfg;
using Daocfg.Models.Account;
using IBatisNet.DataMapper;
using IBatisNet.DataMapper.Exceptions;
using Polly;
using Polly.CircuitBreaker;
using Polly.Timeout;


class PolicyTest
    {
        /// <summary>
        /// mapper
        /// </summary>
        private static readonly ISqlMapper mapper;

        private static readonly Dictionary<int, string> SqlErrorNumbers = new Dictionary<int, string>
            {
                { -2, "超时时间已到。 超时时间在操作完成或服务器没有响应之前已过。" },
                { -1, "在建立与服务器的连接时出错。  服务器不支持请求的协议 " },
                { 2, "在建立与服务器的连接时出错。无法打开到 SQL Server 的连接" },
                { 53, "在建立与服务器的连接时出错。无法打开到 SQL Server 的连接"  },
            };

        //触发熔断的连续错误阈值
        private static readonly int ExceptionsAllowedBeforeBreaking = 3;
        //熔断的时间窗口
        private static readonly int DurationOfBreak = 5;

        private static readonly Policy PolicyInstance;
        static PolicyTest()
        {
            mapper = NewSqlMapper.Instance();
            Policy mainPolicy = Policy.Handle<TimeoutException>()
                    .Or<TimeoutRejectedException>(ex => true)
                    .Or<WebException>(ex => ex.Status == WebExceptionStatus.Timeout)
                    .Or<SqlException>(ex => SqlErrorNumbers.Keys.Contains(ex.Number))
                    .Or<DataMapperException>(ex => ex.Message.StartsWith("Unable to open connection", StringComparison.OrdinalIgnoreCase))
                    .CircuitBreaker(ExceptionsAllowedBeforeBreaking, TimeSpan.FromSeconds(DurationOfBreak), (exception, span,
                        arg3) =>
                    {

                    }, (context) =>
                    {

                    });
            Policy policytimeout = Policy.Timeout(1, TimeoutStrategy.Pessimistic);
            PolicyInstance = mainPolicy.Wrap(policytimeout);
        }

        public static void Excute()
        {
            for (int i = 1; i <= 20; i++)
            {
                Console.WriteLine("当前为第" + i.ToString() + "次请求...");
                try
                {
                    PolicyInstance.Execute(() =>
                    {
                        Console.WriteLine("开始任务!");
                        Thread.Sleep(1100);
                        var list = mapper.QueryForList<AccountDao>("qryAccount", new AccountFilter()
                        {
                            CustomerId = 1357,
                        });
                        Console.WriteLine("完成任务!帐号信息:" + String.Join(",", list));
                    });
                }
                catch (BrokenCircuitException ex)
                {
                    Console.Write("触发熔断!");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("execute出错" + ex.GetType().FullName);
                }

                Thread.Sleep(100);
            }
        }
    }

 

posted @ 2019-01-17 18:09  zslm___  阅读(1248)  评论(0编辑  收藏  举报