说明:

1、Polly官网:http://www.thepollyproject.org/

2、Polly安装:Nuget Microsoft.Extensions.Http.Polly

熔断:熔断开启之后,在熔断过程中将不再发送http请求,而是直接抛异常出来。等到熔断被自动关闭后再正常请求。

降级:熔断开启之后会抛出异常,降级机制则会捕获异常,然后可以进行自定义处理异常。

超时:Http请求的超时时间。

重试:Http请求失败后的重试,可以重试N次。

一、基本使用

1、在Startup.cs类中 ConfigureServices方法配置

//断路器
services.AddHttpClient("small")//降级.AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(fallbackResponse, async b =>{// 1、降级打印异常Console.WriteLine($"服务开始降级,异常消息:{b.Exception.Message}");// 2、降级后的数据//Console.WriteLine($"服务降级内容响应:{fallbackResponse.Content.ToString()}");await Task.CompletedTask;}))//熔断                                                      .AddPolicyHandler(Policy<HttpResponseMessage> // HttpResponseMessage 为HttpClient的返回值.Handle<Exception>() //捕获Exception异常.CircuitBreakerAsync(8,    // 出现3次异常TimeSpan.FromSeconds(20), // 断路器的时间(例如:设置为2秒,短路器两秒后自动由开启到关闭)(ex, ts) =>{//熔断器开启事件触发Console.WriteLine($"服务断路器开启,异常消息:{ex.Exception.Message}");Console.WriteLine($"服务断路器开启的时间:{ts.TotalSeconds}s");}, //断路器重置事件触发() => {Console.WriteLine($"服务断路器重置");}, //断路器半开启事件触发() => {Console.WriteLine($"服务断路器半开启(一会开,一会关)");}))//失败重试.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().RetryAsync(3))//失败重试三次//超时.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(2)));//设置2秒超时时间

2、使用HttpClient来发起请求

private readonly IHttpClientFactory _httpClientFactory;
public TeamService(IHttpClientFactory httpClientFactory)
{_httpClientFactory = httpClientFactory;
}
public async Task<TeamInfo> GetTeamInfos()
{for (int i = 0; i < 15; i++){try{Thread.Sleep(1000);using HttpClient httpClient = _httpClientFactory.CreateClient("small");//访问一个不存在的地址,这个时候会抛异常出来,会触发熔断机制HttpResponseMessage requestResult = await httpClient.GetAsync($"https://localhost:5001/api/test");}catch (Exception ex){Console.WriteLine("异常信息:" + ex.Message);}}return null;
}

二、封装使用

2.1 新建配置文件:pollyconfig.json

{"Polly": [{"ServiceName": [ "Serivce_Team", "Serivce_Member" ], //服务名称,可以多个服务使用同一个配置"TimeoutTime": 5, //超时时间设置,单位为秒"RetryCount": 2, //失败重试次数"CircuitBreakerOpenFallCount": 2, //执行多少次异常,开启短路器(例:失败2次,开启断路器)"CircuitBreakerDownTime": 6, //断路器关闭的时间(例如:设置为2秒,短路器两秒后自动由开启到关闭)"HttpResponseMessage": "系统繁忙,请稍后再试!", //降级处理提示信息"HttpResponseStatus": 200 //降级处理响应状态码},{"ServiceName": [ "Serivce_Team" ], //假如服务名称存在相同的,则后面的会替换掉前面的"TimeoutTime": 2,"RetryCount": 5,"CircuitBreakerOpenFallCount": 2,"CircuitBreakerDownTime": 8,"HttpResponseMessage": "系统繁忙,请稍后再试~!","HttpResponseStatus": 503}]
}

2.2 创建配置实体类:PollyHttpClientConfig.cs

public class PollyHttpClientConfig
{/// <summary>/// 服务名称/// </summary>public List<string> ServiceName { set; get; }/// <summary>/// 超时时间设置,单位为秒/// </summary>public int TimeoutTime { set; get; }/// <summary>/// 失败重试次数/// </summary>public int RetryCount { set; get; }/// <summary>/// 执行多少次异常,开启短路器(例:失败2次,开启断路器)/// </summary>public int CircuitBreakerOpenFallCount { set; get; }/// <summary>/// 断路器关闭的时间(例如:设置为2秒,短路器两秒后自动由开启到关闭)/// </summary>public int CircuitBreakerDownTime { set; get; }/// <summary>/// 降级处理消息(将异常消息封装成为正常消息返回,然后进行响应处理,例如:系统正在繁忙,请稍后处理.....)/// </summary>public string HttpResponseMessage { set; get; }/// <summary>/// 降级处理状态码(将异常消息封装成为正常消息返回,然后进行响应处理,例如:系统正在繁忙,请稍后处理.....)/// </summary>public int HttpResponseStatus { set; get; }
}

2.3 封装拓展类:PollyHttpClientServiceCollectionExtension.cs

public static class PollyHttpClientServiceCollectionExtension{public static void AddPollyHttpClient(this IServiceCollection service){//读取服务配置文件try{var config = new ConfigurationBuilder().AddJsonFile("pollyconfig.json").Build(); //nuget: Microsoft.Extensions.Configuration.JsonList<PollyHttpClientConfig> configList = config.GetSection("Polly").Get<List<PollyHttpClientConfig>>(); // nuget: Microsoft.Extensions.Options.ConfigurationExtensionsif (configList != null && configList.Count > 0){configList.ForEach((pollyHttpClientConfig) =>{service.AddPollyHttpClient(pollyHttpClientConfig);});}}catch (Exception ex){throw new Exception("请正确配置pollyconfig.json");}}public static void AddPollyHttpClient(this IServiceCollection service, PollyHttpClientConfig pollyHttpClientConfig){if (pollyHttpClientConfig == null)throw new Exception("请配置:pollyHttpClientConfig");if (pollyHttpClientConfig.ServiceName == null || pollyHttpClientConfig.ServiceName.Count < 1)throw new Exception("请配置:pollyHttpClientConfig.Polly.ServiceName");for (int i = 0; i < pollyHttpClientConfig.ServiceName.Count; i++){var builder = service.AddHttpClient(pollyHttpClientConfig.ServiceName[i]);builder.BuildFallbackAsync(pollyHttpClientConfig.HttpResponseMessage, pollyHttpClientConfig.HttpResponseStatus);builder.BuildCircuitBreakerAsync(pollyHttpClientConfig.CircuitBreakerOpenFallCount, pollyHttpClientConfig.CircuitBreakerDownTime);builder.BuildRetryAsync(pollyHttpClientConfig.RetryCount);builder.BuildTimeoutAsync(pollyHttpClientConfig.TimeoutTime);}}//降级private static void BuildFallbackAsync(this IHttpClientBuilder builder, string httpResponseMessage, int httpResponseStatus){if (httpResponseStatus < 1 || string.IsNullOrEmpty(httpResponseMessage))return;HttpResponseMessage fallbackResponse = new HttpResponseMessage{Content = new StringContent(httpResponseMessage),StatusCode = (HttpStatusCode)httpResponseStatus};builder.AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(fallbackResponse, async b =>{// 1、降级打印异常Console.WriteLine($"服务开始降级,异常消息:{b.Exception.Message}");// 2、降级后的数据//Console.WriteLine($"服务降级内容响应:{fallbackResponse.Content.ToString()}");await Task.CompletedTask;}));}//熔断private static void BuildCircuitBreakerAsync(this IHttpClientBuilder builder, int circuitBreakerOpenFallCount, int circuitBreakerDownTime){if (circuitBreakerOpenFallCount < 1 || circuitBreakerDownTime < 1)return;builder.AddPolicyHandler(Policy<HttpResponseMessage> // HttpResponseMessage 为HttpClient的返回值.Handle<Exception>() //捕获Exception异常.CircuitBreakerAsync(circuitBreakerOpenFallCount,    // 出现3次异常TimeSpan.FromSeconds(circuitBreakerDownTime), //10秒之内; 结合上面就是:10秒之内出现3次异常就熔断   (ex, ts) =>{   //熔断器开启事件触发Console.WriteLine($"服务断路器开启,异常消息:{ex.Exception.Message}");Console.WriteLine($"服务断路器开启的时间:{ts.TotalSeconds}s");}, //断路器重置事件触发() => { Console.WriteLine($"服务断路器重置"); }, //断路器半开启事件触发() => { Console.WriteLine($"服务断路器半开启(一会开,一会关)"); }));}//失败重试private static void BuildRetryAsync(this IHttpClientBuilder builder, int retryCount){if (retryCount > 0)//失败重试builder.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().RetryAsync(retryCount));}//超时private static void BuildTimeoutAsync(this IHttpClientBuilder builder, int timeoutTime){if (timeoutTime > 0)//超时builder.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(timeoutTime)));}}

2.4 在startup.cs类的ConfigureServices方法中使用

services.AddPollyHttpClient();

.Net Core 微服务使用Polly实现熔断、降级、超时、重试相关推荐

  1. .NET Core 微服务之Polly熔断策略

    紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间内熔断该服务的调用,熔断期间的请求将不再继续调 ...

  2. .NET Core微服务之基于MassTransit实现数据最终一致性(Part 1)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.预备知识:数据一致性 关于数据一致性的文章,园子里已经有很多了,如果你还不了解,那么可以通过以下的几篇文章去快速地了解了解,有个感性认 ...

  3. .NET Core微服务之路:不断更新中的目录 (v0.42)

    原文:.NET Core微服务之路:不断更新中的目录 (v0.42) 微服务架构,对于从事JAVA架构的童鞋来说,早已不是什么新鲜的事儿,他们有鼎鼎大名的Spring Cloud这样的全家桶框架支撑, ...

  4. .NET Core微服务之基于Consul实现服务治理

    一.Consul基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,比如 Airbnb的SmartStack等相比,Co ...

  5. .NET Core微服务系列基础文章索引(目录导航Final版)

    一.为啥要总结和收集这个系列? 今年从原来的Team里面被抽出来加入了新的Team,开始做Java微服务的开发工作,接触了Spring Boot, Spring Cloud等技术栈,对微服务这种架构有 ...

  6. .NET Core微服务之基于Consul实现服务治理(续)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 上一篇发布之后,很多人点赞和评论,不胜惶恐,这一篇把上一篇没有弄到的东西补一下,也算是给各位前来询问的朋友的一些回复吧. 一.Consul ...

  7. .NET Core微服务之基于Ocelot实现API网关服务(续)

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.负载均衡与请求缓存 1.1 负载均衡 为了验证负载均衡,这里我们配置了两个Consul Client节点,其中ClientServic ...

  8. .NET Core 微服务学习与实践系列文章目录索引(2019版)

    Photo :.NET Core 文 | Edison Zhou 2018年,我开始学习和实践.NET Core,并开始了微服务的学习,以及通过各种开源组件搭建服务治理技术方案,并在学习过程中总结了一 ...

  9. asp.net core 使用HttpClientFactory Polly实现熔断降级

    前言 在NET Core2.1后也是增加更新了很多东西,当然HttpClientFactory更新中的一部分.虽然说HttpClient这个实现了disposable,但使用它的时候用using包装块 ...

最新文章

  1. 【贪心】【codevs】1214 线段覆盖
  2. vim中权限不足时不用退出而强制保存
  3. 人工智能军备竞赛:一文尽览全球主要国家AI战略
  4. Windows下为PHP安装redis扩展
  5. linux如何导入种子文件格式,在 Linux 上使用 transmission 制作种子
  6. Redis-学习笔记03【Redis持久化】
  7. spring的log4j listener(webAppRootKey)
  8. 执行Bean 实例化
  9. 今天看明白了,为什么有些属性会这样写了:public string status{get;set;}
  10. linux barrier,如何决定何时启用Linux文件系统barrier功能?
  11. 51单片机几种精确延时(包含自动适应主时钟)
  12. Java JSON转Excel工具类
  13. PayPal注册和认证说明,招商银行信用卡和牡丹国际借记卡
  14. Vue 快速搭建页面模板
  15. SAP项目上的疑难杂症-(制品区分)如何处理?
  16. windows粘贴不了
  17. 每个程序员都应该知道的GitHub Repos
  18. 前端将List列表转化为树型结构(reduce函数)
  19. 商品库存推送至外部系统API接口文档
  20. 基于matlab多功能相控阵雷达资源管理的服务质量优化

热门文章

  1. MySQL项目八总结
  2. contentType与dataType
  3. 【图神经网络DGL】GCN在Karate Club上的实战(消息传递范式 | 生成训练可视化动图)
  4. 【Springboot + Vue 视频播放web项目】解决视频播放只有声音没有画面
  5. VS安装扩展缓慢问题解决
  6. JAVA——实现循环录入学员Java课程的成绩(学员数量由键盘录入),统计分数大于等于80分的学生的比例。
  7. vue 校验规则 防止多次点击弹窗重新触发
  8. 重庆工商职业学院计算机类宿舍,重庆工商职业学院宿舍条件,宿舍图片和环境空调及分配方法...
  9. chanson:Ta fete 翻译
  10. oracle 创建同义词