• .NET5微服务示例-Polly熔断与降级


    什么是Polly:https://www.cnblogs.com/lwqlun/p/8119856.html

    策略示例:https://www.cnblogs.com/TianFang/archive/2018/01/06.html

    控制台简单示例(需Nuget安装Polly包)

    using Polly;
    using Polly.Timeout;
    using System;
    using System.Threading;
    
    namespace ConsoleApp2
    {
        class Program
        {
            static void Main(string[] args)
            {
                //Method1();
                //string s2 = Method2();
                //Method3();
                //Method4();
                //Method5();
                //Method6();
                Console.ReadKey();
            }
    
            /// <summary>
            /// 普通使用
            /// </summary>
            static void Method1()
            {
                //指定捕获ArgumentException异常,如果不是ArgumentException,那么Fallback就捕获不到
                Policy.Handle<ArgumentException>() 
                    .Fallback(() =>
                    {
                        Console.WriteLine("出现错误了");
                    }, ex => //可以拿到Fallback的异常信息
                    {
                        Console.WriteLine($"异常信息:{ex.Message}");
                    })
                    //执行业务操作
                    .Execute(() =>
                    {
                        Console.WriteLine("开始");
                        throw new ArgumentException("异常了!");
                        Console.WriteLine("结束");
                    });
            }
    
            /// <summary>
            /// 带返回值
            /// </summary>
            static string Method2()
            {
                var policy = Policy<string>.Handle<ArgumentException>()
                    .Fallback("Fallback的返回值");
                var result = policy.Execute(() =>
                    {
                        //throw new ArgumentException("异常了!");
                        return "Execute的返回值";
                    });
                //如果Execute中出现了ArgumentException异常,那么result将会得到Fallback的返回值
                return result;
            }
    
            /// <summary>
            /// 重试示例
            /// </summary>
            static void Method3()
            {
                Policy.Handle<ArgumentException>()
                    //.Retry(3) //不填数字默认重试一次
                    //.WaitAndRetry(3, i => TimeSpan.FromSeconds(1)) //重试3次,每次等待1秒后再重试
                    .RetryForever() //不停重试
                    .Execute(() =>
                    {
                        Console.WriteLine("开始");
                        if (DateTime.Now.Second % 10 != 0)
                        {
                            throw new ArgumentException("异常了!");
                        }
                        Console.WriteLine("结束");
                    });
            }
    
            /// <summary>
            /// 断路保护
            /// </summary>
            static void Method4()
            {
                var policy = Policy.Handle<ArgumentException>()
                    .CircuitBreaker(2, TimeSpan.FromSeconds(5)); //连续出错2次后熔断5秒
    
                while (true)
                {
                    try
                    {
                        policy.Execute(() =>
                        {
                            Console.WriteLine("开始");
                            throw new ArgumentException("异常了!");
                            Console.WriteLine("结束");
                        });
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    Thread.Sleep(1000);
                }
            }
    
            /// <summary>
            /// 策略封装-重试
            /// </summary>
            static void Method5()
            {
                var policyRetry = Policy.Handle<ArgumentException>().Retry(3);
                var policyFallback = Policy.Handle<ArgumentException>()
                    .Fallback(()=>{
                        Console.WriteLine("Fallback");
                    });
                //如果policyRetry重试3次后还有故障,就把故障抛给policyFallback处理
                var policy = policyFallback.Wrap(policyRetry);
                policy.Execute(() =>
                {
                    Console.WriteLine("开始");
                    throw new ArgumentException("异常了!");
                    Console.WriteLine("结束");
                });
            }
    
            /// <summary>
            /// 策略封装-超时
            /// </summary>
            static void Method6()
            {
                //Pessimistic悲观的超时策略,通过其他方式保证超时(并返回给调用者)
                var policyTimeout = Policy.Timeout(3, TimeoutStrategy.Pessimistic);
                var policyFallback = Policy.Handle<TimeoutRejectedException>() //超时策略就是抛出这个异常的
                    .Fallback(() => {
                        Console.WriteLine("Fallback");
                    });
                var policy = policyFallback.Wrap(policyTimeout);
                policy.Execute(() =>
                {
                    Console.WriteLine("开始");
                    Thread.Sleep(5000); //模拟超时5秒
                    Console.WriteLine("结束");
                });
            }
        }
    }
    View Code

    接着这篇文章:.NET5微服务示例-Consul注册中心

    1、SGZ.Framework下安装Nuget包“Microsoft.Extensions.Http.Polly”

    2、Extentions文件夹下新增扩展类PollyServiceCollectionExtension

    using Microsoft.Extensions.DependencyInjection;
    using Polly;
    using SGZ.Framework.Models;
    using System;
    using System.Net.Http;
    
    namespace SGZ.Framework.Extentions
    {
        public static class PollyServiceCollectionExtension
        {
            public static IServiceCollection AddPollyHttpClient(this IServiceCollection services, string name, PollyConfig config)
            {
                services.AddHttpClient(name)
                    .AddPolicyHandler(
                        Policy<HttpResponseMessage>
                        .Handle<ExecutionRejectedException>() // 捕获所有的Polly异常
                        .FallbackAsync(config.httpResponseMessage)
                    )
                    .AddPolicyHandler( //熔断策略
                        Policy<HttpResponseMessage>
                        .Handle<Exception>()
                        .CircuitBreakerAsync(
                            config.CircuitBreakerOpenFallCount
                            , TimeSpan.FromSeconds(config.CircuitBreakerDownTime)
                        )
                    )
                    .AddPolicyHandler( //超时策略
                        Policy.TimeoutAsync<HttpResponseMessage>(config.TimeoutTime)
                    ) 
                    .AddPolicyHandler( //重试策略
                        Policy<HttpResponseMessage>
                        .Handle<Exception>()
                        .RetryAsync(config.RetryCount)
                    )
                    .AddPolicyHandler( //资源隔离
                        //保证每一个服务都是固定的线程,防止一个服务占用过多线程而影响其它服务
                        Policy.BulkheadAsync<HttpResponseMessage>(10, 100)
                    );
                return services;
            }
        }
    }

    3、SGZ.AggregationService的Startup类,ConfigureServices方法增加各个服务的Polly配置

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
    
        services.AddConsul(Configuration);
    
        services.AddLoadBalance();
    
        #region Polly相关
        services.AddPollyHttpClient("DepartmentService", new PollyConfig
        {
            RetryCount = 2,
            TimeoutTime = 10,
            CircuitBreakerDownTime = 10,
            CircuitBreakerOpenFallCount = 2,
            httpResponseMessage = new HttpResponseMessage
            {
                Content = new StringContent("系统正繁忙,请稍后重试"),
                StatusCode = HttpStatusCode.BadGateway
            }
        });
    
        services.AddPollyHttpClient("PersonnelService", new PollyConfig
        {
            RetryCount = 2,
            TimeoutTime = 10,
            CircuitBreakerDownTime = 10,
            CircuitBreakerOpenFallCount = 2,
            httpResponseMessage = new HttpResponseMessage
            {
                Content = new StringContent("系统正繁忙,请稍后重试"),
                StatusCode = HttpStatusCode.BadGateway
            }
        }); 
        #endregion
    
        services.AddServiceRequest();
    }

    4、运行方式也如上一篇文章那样执行

    本文代码:https://files.cnblogs.com/files/shousiji/net5_polly.rar

  • 相关阅读:
    SQL SERVER开窗函数
    SQL SERVER调优常用方法
    SQL SERVER其它函数
    SQL SERVER时间函数
    SQL SERVER字符串函数
    ptyhon技能树及其学习资源
    机器学习中的数学基础
    python-spider 第10题
    python-spider 第七关
    python-spider 第六关
  • 原文地址:https://www.cnblogs.com/shousiji/p/15268215.html
Copyright © 2020-2023  润新知