本文主要介绍 HttpClientFactory
整合 Polly 的使用,实现对 Http 请求的超时、重试、熔断、降级等操作。
HttpClientFactory 集成 Polly
-
创建 .NET Core API 项目(这里使用的是 .NET Core 2.2);
-
安装
Microsoft.Extensions.Http.Polly
NuGet Package; -
在 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
定义一个名为github
的HttpClient
,后续可通过名称获取到这个 HttpClient 对象来发送 Http 请求; - 通过
AddPolicyHandler
(其他扩展方法参考:Polly and HttpClientFactoryAddTransientHttpErrorPolicy
、AddPolicyHandlerFromRegistry
的使用介绍) 为此HttpClient
添加Polly
策略; - 设置降级策略,当出现任何异常,返回
fallbackResponse
; - 设置熔断策略,当连续出现
TimeoutRejectedException
异常 5 次,熔断 3s; - 设置重试策略,当出现
TimeoutRejectedException
分别等待 100ms、200ms 后重试; - 设置超时策略,请求超时为 0.5s,超时默认会抛出
TimeoutRejectedException
; - 当多个策略叠加时,最先起作用的是最后添加的;
- 通过
-
使用 HttpClient
public class ValuesController : ControllerBase { private readonly IHttpClientFactory _httpClientFactory; public ValuesController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } [HttpGet] public async Task
> 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
中获取定义好的名为github
的HttpClient
对象,和普通的HttpClient
的区别是此HttpClient
已具有定义的各种Polly
策略,其他没任何区别;
转:https://www.jianshu.com/p/f4444c04b05c