asp.net core 使用HttpClientFactory Polly實現熔斷降級

前言

NET Core2.1後也是增長更新了不少東西,固然HttpClientFactory更新中的一部分.雖說HttpClient這個實現了disposable,但使用它的時候用using包裝塊的方式一般不是最好的選擇。處理HttpClient,底層socket套接字不會當即釋放。該HttpClient類是未多個請求重複使用而建立的。須要不一樣的基地址,不一樣的HTTP 標頭和其餘對請求個性化操做的場景時,須要動手管理多個HttpClient實例,爲了簡化HttpClient實例管理,.NET Core 2.1提供了一個新的HTTPClientFactory - 它能夠建立,緩存和處理HttpClient實例。git

什麼是HttpClientFactory

ASPNET Core開始,PollyIHttpClientFastory集成。HttpClientFastory是一個簡化管理和使用的HttpClientory。用ASP.Net團隊的話說:「an opinionated factory for creating HttpClient instances」(一個用於建立HttpClient實例的最佳實踐的工廠github

  • 提供命名和配置邏輯HttpClient 對象的中心位置。例如,您能夠配置預先配置爲訪問特定微服務的客戶端(服務代理)。
  • 經過委派處理程序HttpClient 並實施基於Polly 的中間件來利用Polly 的彈性策略,對傳出中間件的概念進行編碼。
  • HttpClient 已經有了委託處理程序的概念,這些處理程序能夠連接在一塊兒用於傳出HTTP 請求。您將HTTP 客戶端註冊到工廠中,而且可使用Polly處理程序將Polly策略用於RetryCircuitBreakers 等。
  • 管理生命週期,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 的配置。) json

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

Startupapi

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));

    }

設置降級策略當出現任何異常返回fallbackapp

設置熔斷策略當連續出現異常異常 2 次,熔斷 4s;socket

設置超時策略,請求超時爲 1s,超時默認會拋出 TimeoutRejectedException;async

效果以下微服務

概要

示例地址:https://github.com/fhcodegit/HttpClientFactoryPolly Polly:https://github.com/App-vNext/Polly 參考:http://www.javashuo.com/article/p-kmdmyiuk-mw.htmlui

相關文章
相關標籤/搜索