转载

HttpClientFactory + Polly 实现熔断降级

HttpClientFactory 是 ASP.NET CORE 2.1 中新增加的功能,目的是为了解决直接使用 HttpClient 可能带来的一系列问题( 优雅通过 HttpClientFactory 使用 HttpClient ),本文主要介绍 HttpClientFactory 整合 Polly 的使用,实现对 Http 请求的超时、重试、熔断、降级等操作。

HttpClientFactory 集成 Polly

  1. 创建 .NET Core API 项目(这里使用的是 .NET Core 2.2);

  2. 安装 Microsoft.Extensions.Http.Polly NuGet Package;

  3. 在 Startup.cs 的 ConfigureServices 方法中添加 HttpClient 相关代码:

    public void ConfigureServices(IServiceCollection services)
    {
    		var fallbackResponse = new HttpResponseMessage
    		{
    				Content = new StringContent("Fallback"),
    				StatusCode = HttpStatusCode.GatewayTimeout
    		};
    
    		services.AddHttpClient("github", client =>
    		{
    				client.BaseAddress = new Uri("https://www.github.com");
    		})
    		// 降级
    		.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().FallbackAsync(fallbackResponse, async b =>
    		 {
    				 await Task.CompletedTask;
    				 _logger.LogWarning($"Fallback: {b.Exception.Message}");
    		 }))
    		// 熔断
    		.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<TimeoutRejectedException>().CircuitBreakerAsync(5, TimeSpan.FromSeconds(3), (ex, ts) =>
    		{
    				_logger.LogWarning($"Open Circuit Breaker:{ts.TotalMilliseconds}");
    		}, () =>
    		{
    				_logger.LogWarning($"Closed Circuit Breaker");
    		}, () =>
    		{
    				_logger.LogWarning($"HalfOpen Circuit Breaker");
    		}))
    		// 重试
    		.AddPolicyHandler(Policy<HttpResponseMessage>
    				.Handle<TimeoutRejectedException>()
    				.WaitAndRetryAsync(
    								new[]
    								{
    										TimeSpan.FromMilliseconds(100),
    										TimeSpan.FromMilliseconds(200)
    								}
    						)
    		)
    		// 超时
    		.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(0.5)));
    
    		services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }
    

    说明( 这部分代码在实际使用中建议重新封装,不应该每次都为当前定义的 HttpClient 设置一堆重复代码 ):

    • 通过 services.AddHttpClient 定义一个名为 githubHttpClient ,后续可通过名称获取到这个 HttpClient 对象来发送 Http 请求;
    • 通过 AddPolicyHandler 其他扩展方法参考: Polly and HttpClientFactory AddTransientHttpErrorPolicyAddPolicyHandlerFromRegistry 的使用介绍 ) 为此 HttpClient 添加 Polly 策略;
    • 设置降级策略,当出现任何异常,返回 fallbackResponse
    • 设置熔断策略,当连续出现 TimeoutRejectedException 异常 5 次,熔断 3s;
    • 设置重试策略,当出现 TimeoutRejectedException 分别等待 100ms、200ms 后重试;
    • 设置超时策略,请求超时为 0.5s,超时默认会抛出 TimeoutRejectedException
    • 当多个策略叠加时,最先起作用的是最后添加的;
  4. 使用 HttpClient

    public class ValuesController : ControllerBase
    {
    		private readonly IHttpClientFactory _httpClientFactory;
    
    		public ValuesController(IHttpClientFactory httpClientFactory)
    		{
    				_httpClientFactory = httpClientFactory;
    		}
    
    		[HttpGet]
    		public async Task<ActionResult> Get()
    		{
    				var client = _httpClientFactory.CreateClient("github");
    				var request = new HttpRequestMessage(HttpMethod.Get, "/");
    				var response = await client.SendAsync(request);
    				var result = await response.Content.ReadAsStringAsync();
    				return Ok(result);
    		}
    }
    

    说明:从 HttpClientFactory 中获取定义好的名为 githubHttpClient 对象,和普通的 HttpClient 的区别是此 HttpClient 已具有定义的各种 Polly 策略,其他没任何区别;

  5. 效果测试

    Timeout Retry

    HttpClientFactory + Polly 实现熔断降级

    Timeout Circuit Breaker

    HttpClientFactory + Polly 实现熔断降级

    HttpClientFactory + Polly 实现熔断降级

    HttpClientFactory + Polly 实现熔断降级

    Fallback

    HttpClientFactory + Polly 实现熔断降级

参考链接

  • Polly
  • Polly and HttpClientFactory
  • 优雅通过 HttpClientFactory 使用 HttpClient
原文  http://beckjin.com/2019/09/07/polly-http-client/
正文到此结束
Loading...