.Net Core 使用Http請求及基於 Polly 的處理故障

1、介紹json

  在IServiceCollection調用AddHttpClient註冊IHttpClientFactory服務,調用AddHttpMessageHandler以生成出站請求中間件管道。 每一個處理程序均可以在出站請求先後執行工做。經過Polly 的處理程序,以表達策略處理重試、斷路器、超時、隔離和回退。安全

2、使用http請求app

1.配置註冊async

var host = new HostBuilder()
      .ConfigureServices((context, services) => {
            services.AddHttpClient();
            services.AddHostedService<MyHostedService>();
      })
      .UseConsoleLifetime()
      .Build();

2.請求的後臺服務ide

public Task StartAsync(CancellationToken cancellationToken)
        {
            return Task.Run(async () =>
            {
                var request = new HttpRequestMessage(HttpMethod.Post, "http://www.baidu.com");
                request.Headers.Add("Accept", "application/json");//設置請求頭
                request.Properties.Add("id","123");//設置請求參數
                var client = _clientFactory.CreateClient();
                var response = await client.SendAsync(request);
                string result = null;
                if (response.IsSuccessStatusCode)
                {
                    result = await response.Content.ReadAsStringAsync();
                }
            });
        }

 3.執行時控制檯輸入日誌ui

2、以客戶端的方式使用spa

在客戶端中配置,默認請求Url地址和默認的header。線程

public class HaosRequestService
    {
        public HttpClient Client { get; }

        public HaosRequestService(HttpClient client)
        {
            //配置默認值
            client.BaseAddress = new Uri("http://www.baidu.com/");
            client.DefaultRequestHeaders.Add("Accept","application/json");
            Client = client;
        }
        /// <summary>
        /// 封裝經常使用方法
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public async Task<string> SeachAsync(string key)
        {
            var content = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string,string>("w","關鍵字"),
            });
            var response = await Client.PostAsync("/s",content);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadAsStringAsync();
        }
    }

在IServiceCollection中註冊日誌

var host = new HostBuilder()
                .ConfigureServices((context, services) => {
                    services.AddHttpClient<HaosRequestService>();
                    services.AddHostedService<MyHostedService>();
                })

3、處理出站 HTTP 請求code

 IHttpClientFactory 能夠爲客戶端定義處理程,支持註冊和連接多個處理程序。要建立處理程序,先定義一個繼承 DelegatingHandler 的類。 重寫 SendAsync 方法,在將請求傳遞至管道中的下一個處理程序以前

 

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace Haos.Develop.HttpRequest.Samples
{
    public class ColationDelegatingHandler:DelegatingHandler
    {
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            //此處實現過濾邏輯
            return base.SendAsync(request, cancellationToken);
        }
    }
}

 

var Host = new HostBuilder()
    .ConfigureAppConfiguration(builder =>
    {
        builder.AddCommandLine(args);
    })
    .ConfigureServices((context, services) =>
    {
        services.AddHttpClient<RequestClient>()
        //註冊過濾程序
        .AddHttpMessageHandler<ColationDelegatingHandler>();
    })
    .UseConsoleLifetime()
    .Build();

 

4、基於Polly的處理程序

  Polly 以表達策略,例如以流暢且線程安全的方式處理重試、斷路器、超時、Bulkhead 隔離和回退。Microsoft.Extensions.Http.Polly NuGet 包中提供 Polly 擴展實現將 Polly 策略用於配置的 HttpClient 實例。 

  Polly 添加策略分爲三種

    1. AddTransientHttpErrorPolicy:是處理Http請求的錯誤,如HTTP 5XX 的狀態碼,HTTP 408 的狀態碼 以及System.Net.Http.HttpRequestException異常

    2. AddPolicyHandler:添加自定義策列

    3. AddPolicyHandlerFromRegistry:從Policy註冊表集合裏面選擇添加

  a. AddTransientHttpErrorPolicy

.ConfigureServices((context, services) =>
{
    services.AddHttpClient<RequestClient>()
    .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(500)))
    //或。上下都是定義了,錯誤重試上面是間隔都是500毫秒,下面則定義了每次重試的時間間隔
    .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[] {
        TimeSpan.FromSeconds(1),
        TimeSpan.FromSeconds(5),
        TimeSpan.FromSeconds(10)
    }));
})

  b. AddPolicyHandler

  先定義策略,在經過AddPolicyHandler方法添加,改方法接收一個泛型的IAsyncPolicy<HttpResponseMessage>。HttpResponseMessage我理解爲出站請求上下文

.ConfigureServices((context, services) =>
{
    var retryPolicy = Policy.Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(response => {
        //此處實現處理改異常的邏輯
        return true;
    }).WaitAndRetryAsync(3,t => TimeSpan.FromMilliseconds(50));

    services.AddHttpClient<RequestClient>()
    .AddPolicyHandler(retryPolicy);
})
retryPolicy:發生HttpRequestException的異常,而且OrResult返回結果爲true,採用這個策略

  c. AddPolicyHandlerFromRegistry

  先註冊策略表服務,爲策略表添加策略,最後經過AddPolicyHandlerFromRegistry方法選用某個或幾個策略

.ConfigureServices((context, services) =>
{
    //註冊,策略表服務
    var registry = services.AddPolicyRegistry();
    //建立策略
    var retryPolicy = Policy.Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(response => {
        //此處實現處理改異常的邏輯
        return true;
    }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50));
    registry.Add("registry1", retryPolicy);
    services.AddHttpClient<RequestClient>()
    .AddPolicyHandlerFromRegistry("registry1");
})

  添加多個 Polly 處理程序嵌套 Polly 策略以加強功

    分別定義三種策略,timeoutPolicy,noOpPolicy,retryPolicy 經過策略表的方式和自定義。添加多個策略。

.ConfigureServices((context, services) =>
{
    //註冊,策略表服務
    var registry = services.AddPolicyRegistry();
    //建立策略
    var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10);//10秒超時
    var noOpPolicy = Policy.NoOpAsync().AsAsyncPolicy<HttpResponseMessage>();//有時咱們也須要一個沒有任何行爲的策略,Polly系統默認提供了一個.
    var retryPolicy = Policy.Handle<HttpRequestException>()
    .OrResult<HttpResponseMessage>(response => {
        //此處實現處理改異常的邏輯
        return true;
    }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50));
    registry.Add("registry1", retryPolicy);
    registry.Add("registry2", timeoutPolicy);
    services.AddHttpClient<RequestClient>()
    .AddPolicyHandlerFromRegistry("registry1")
    .AddPolicyHandler(retryPolicy)
    .AddPolicyHandler(timeoutPolicy);
})
相關文章
相關標籤/搜索