ASP.NET Core使用HttpClientFactory Polly实现熔断降级

2019 年 9 月 20 日 DotNet

(给DotNet加星标,提升.Net技能


转自: 言诗人
cnblogs.com/yyfh/p/11548776.html

前言


在NET Core2.1后也是增加更新了很多东西,当然HttpClientFactory更新中的一部分.虽然说HttpClient这个实现了disposable,但使用它的时候用using包装块的方式通常不是最好的选择。处理HttpClient,底层socket套接字不会立即释放。该HttpClient类是未多个请求重复使用而创建的。需要不同的基地址,不同的HTTP 标头和其他对请求个性化操作的场景时,需要动手管理多个HttpClient实例,为了简化HttpClient实例管理,.NET Core 2.1提供了一个新的HTTPClientFactory - 它可以创建,缓存和处理HttpClient实例。


什么是HttpClientFactory


从ASPNET Core开始,Polly与IHttpClientFastory集成。HttpClientFastory是一个简化管理和使用的HttpClientory。用ASP.Net团队的话说:“an opinionated factory for creating HttpClient instances”(一个用于创建HttpClient实例的最佳实践的工厂)


  • 提供命名和配置逻辑HttpClient 对象的中心位置。例如,您可以配置预先配置为访问特定微服务的客户端(服务代理)。


  • 通过委派处理程序HttpClient 并实施基于Polly 的中间件来利用Polly 的弹性策略,对传出中间件的概念进行编码。


  • HttpClient 已经有了委托处理程序的概念,这些处理程序可以链接在一起用于传出HTTP 请求。您将HTTP 客户端注册到工厂中,并且可以使用Polly处理程序将Polly策略用于Retry,CircuitBreakers 等。


  • 管理生命周期,HttpClientMessageHandlers 以避免在管理HttpClient 自己的生命周期时可能发生的上述问题/问题。


HttpClientFactory简单使用


  • Startup添加

services.AddHttpClient();
  • 通过IHttpClientFactory创建一个HttpClient对象,后面操作如旧,但是不需要关心其资源释放

using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Threading.Tasks;

namespace HttpClientFactoryPolly.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
public ValuesController(IHttpClientFactory httpClientFactory)
{
this._httpClientFactory = httpClientFactory;
}

// GET api/values
[HttpGet]
public async Task<ActionResult<string>> Get()
{
var client = _httpClientFactory.CreateClient();
var result =await client.GetStringAsync("https://www.microsoft.com/zh-cn/");
return result;
}
}
}


配置HttpClientFactory Polly


这边采用命名客户端演示该子(如果应用需要有许多不同的 HttpClient 用法(每种用法的配置都不同),可以视情况使用命名客户端。可以在 HttpClient 中注册时指定命名 Startup.ConfigureServices 的配置。)



  • Package


PM> Install-package Microsoft.Extensions.Http.Polly


  • Startup


services.AddHttpClient("github",c=> {
//基址
c.BaseAddress = new System.Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

[HttpGet("{id}")]
public async Task<ActionResult<string>> Get(int id)
{
var request = new HttpRequestMessage(HttpMethod.Get,"repos/aspnet/docs/pulls");
var client = _httpClientFactory.CreateClient("github");
var response = await client.SendAsync(request);
var result =await response.Content.ReadAsStringAsync();
return result;
}


  • 重试机制


services.AddHttpClient("github", c =>
{
//基址
c.BaseAddress = new System.Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
//AddTransientHttpErrorPolicy主要是处理Http请求的错误,如HTTP 5XX 的状态码,HTTP 408 的状态码 以及System.Net.Http.HttpRequestException异常
}).AddTransientHttpErrorPolicy(p =>
//WaitAndRetryAsync参数的意思是:每次重试时等待的睡眠持续时间。
p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));


效果如下



  • 熔断降级超时


services.AddHttpClient("test", c =>
{
//基址
c.BaseAddress = new System.Uri("http://localhost:5000/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
})
// 降级
.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().FallbackAsync(fallbackResponse, async b =>
{
Console.WriteLine($"fallback here {b.Exception.Message}");
}))
// 熔断
.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(2, TimeSpan.FromSeconds(4), (ex, ts) =>
{
Console.WriteLine($"break here {ts.TotalMilliseconds}");
}, () =>
{
Console.WriteLine($"reset here ");
}))

// 超时
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(1));
}


设置降级策略当出现任何异常返回fallback


设置熔断策略当连续出现异常异常 2 次,熔断 4s;


设置超时策略,请求超时为 1s,超时默认会抛出 TimeoutRejectedException;


效果如下



示例:https://github.com/fhcodegit/HttpClientFactoryPolly


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


推荐阅读

(点击标题可跳转阅读)

.NET Core 泛型仓储和声明式事物实现最优雅的crud操作

ASP.NET Core 2.2 Action的多种数据返回格式处理机制

.NET Core 3.0 RC 1 发布


看完本文有收获?请转发分享给更多人

关注「DotNet」加星标,提升.Net技能 

好文章,我在看❤️

登录查看更多
4

相关内容

【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【Manning2020新书】Elm 实战,344页pdf,Elm in Action
专知会员服务
49+阅读 · 2020年4月14日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
65+阅读 · 2020年3月9日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
后渗透利用msf关闭防火墙
黑白之道
8+阅读 · 2019年8月24日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
使用 Canal 实现数据异构
性能与架构
20+阅读 · 2019年3月4日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
干货 | 双11总峰值超8亿OPS 阿里分布式NoSQL如何岿然不动稳如山?
阿里巴巴数据库技术
10+阅读 · 2018年12月12日
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
Generating Fact Checking Explanations
Arxiv
9+阅读 · 2020年4月13日
Arxiv
4+阅读 · 2019年8月7日
Arxiv
6+阅读 · 2018年2月7日
VIP会员
相关VIP内容
【实用书】流数据处理,Streaming Data,219页pdf
专知会员服务
76+阅读 · 2020年4月24日
【Manning2020新书】Elm 实战,344页pdf,Elm in Action
专知会员服务
49+阅读 · 2020年4月14日
【2020新书】Kafka实战:Kafka in Action,209页pdf
专知会员服务
65+阅读 · 2020年3月9日
【新书】Java企业微服务,Enterprise Java Microservices,272页pdf
相关资讯
后渗透利用msf关闭防火墙
黑白之道
8+阅读 · 2019年8月24日
浅谈 Kubernetes 在生产环境中的架构
DevOps时代
11+阅读 · 2019年5月8日
使用 Canal 实现数据异构
性能与架构
20+阅读 · 2019年3月4日
一天精通无人中级篇:遥控器协议 S-BUS
无人机
48+阅读 · 2018年12月20日
干货 | 双11总峰值超8亿OPS 阿里分布式NoSQL如何岿然不动稳如山?
阿里巴巴数据库技术
10+阅读 · 2018年12月12日
浅谈浏览器 http 的缓存机制
前端大全
6+阅读 · 2018年1月21日
设计和实现一款轻量级的爬虫框架
架构文摘
13+阅读 · 2018年1月17日
Top
微信扫码咨询专知VIP会员