.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("结束"); }); } } }
接着这篇文章:.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