自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一篇解決在 .NET 8中使用 Polly 處理瞬態(tài)故障

開發(fā) 前端
對(duì)于瞬態(tài)故障,故障持續(xù)時(shí)間通常很短,服務(wù)很快會(huì)恢復(fù)。因此,為了提高容錯(cuò)性,可以在失敗后重試多次,然后再接受失敗結(jié)果。我們可以通過重試策略來處理瞬態(tài)故障,也就是不斷重新嘗試請(qǐng)求,直到成功或達(dá)到重試上限。

在本文中,我們將學(xué)習(xí)如何在與服務(wù)交互時(shí)實(shí)現(xiàn)重試機(jī)制,尤其當(dāng)服務(wù)出現(xiàn)一些瞬態(tài)故障時(shí)。

什么是瞬態(tài)故障?

瞬態(tài)故障是指持續(xù)時(shí)間較短的故障。例如:網(wǎng)絡(luò)連接因路由器重啟而中斷,服務(wù)因部署更新而短暫不可用,或資源耗盡導(dǎo)致連接被拒絕。

對(duì)于瞬態(tài)故障,故障持續(xù)時(shí)間通常很短,服務(wù)很快會(huì)恢復(fù)。因此,為了提高容錯(cuò)性,可以在失敗后重試多次,然后再接受失敗結(jié)果。

我們可以通過重試策略來處理瞬態(tài)故障,也就是不斷重新嘗試請(qǐng)求,直到成功或達(dá)到重試上限。

重試策略的配置選項(xiàng)

  • 重試次數(shù):定義最大重試次數(shù)。
  • 重試間隔時(shí)間:定義每次重試之間的時(shí)間間隔。

本文將介紹三種重試策略:

策略 1:立即重試 5 次

根據(jù)此策略,系統(tǒng)會(huì)連續(xù)重試 5 次請(qǐng)求,直到成功返回響應(yīng)。如果在 5 次重試后仍然失敗,則接受失敗結(jié)果。

圖片圖片

策略 2:重試 5 次并等待 3 秒

根據(jù)此策略,系統(tǒng)在每次重試前等待 3 秒,然后再向響應(yīng)服務(wù)發(fā)出請(qǐng)求。

圖片圖片

策略 3:指數(shù)回退重試 5 次

根據(jù)此策略,系統(tǒng)會(huì)在請(qǐng)求之間采用指數(shù)級(jí)等待時(shí)間,例如 1 秒、3 秒、5 秒、8 秒。

圖片圖片

我們可以使用 Polly 實(shí)現(xiàn)這些重試機(jī)制,并通過基于類的配置實(shí)現(xiàn)。下面開始編碼實(shí)現(xiàn)。

創(chuàng)建響應(yīng)服務(wù)(Response Service)

首先創(chuàng)建一個(gè)新的 .NET Web API 應(yīng)用程序,命名為 Response Service。在 Program.cs 文件中添加控制器映射:

builder.Services.AddSwaggerGen();
builder.Services.AddControllers();
var app = builder.Build();
app.MapControllers();

然后創(chuàng)建一個(gè) ResponseController.cs 文件,添加如下操作方法:

[Route("api/[Controller]")]
[ApiController]
public class ResponseController : ControllerBase
{
    [HttpGet]
    [Route("{id:int}")]
    public ActionResult GetAResponse(int id)
    {
        Random rnd = new Random();
        var rndInteger = rnd.Next(1, 101);

        if (rndInteger >= id)
        {
            Console.WriteLine("Failure - Generate an Internal Error");
            return StatusCode(StatusCodes.Status500InternalServerError);
        }

        Console.WriteLine("Failure - Generated a Success");
        return Ok("Success");
    }
}

在上述代碼中,我們使用 Random 函數(shù)實(shí)現(xiàn)了服務(wù)內(nèi)的瞬態(tài)故障。當(dāng)隨機(jī)生成的整數(shù)小于輸入的 ID 時(shí),有可能返回內(nèi)部服務(wù)器錯(cuò)誤。

運(yùn)行代碼并通過 Postman 測(cè)試。根據(jù)生成的隨機(jī)整數(shù),響應(yīng)服務(wù)的狀態(tài)碼會(huì)隨機(jī)返回 200 或 500。

圖片圖片

創(chuàng)建請(qǐng)求服務(wù)(Request Service)

接下來,創(chuàng)建另一個(gè)新的 .NET Web API 應(yīng)用程序,命名為 Request Service。在 Program.cs 中同樣添加控制器到管道中。

創(chuàng)建 RequestController.cs 文件,用于通過 HttpClient 調(diào)用 API,代碼如下:

namespace RequestService.Controllers
{
    [ApiController]
    [Route("api/[Controller]")]
    public class RequestController: ControllerBase
    {
        public RequestController()
        {
        }
        [HttpGet]
        public async Task<ActionResult> MakeRequest()
        {
           var client = new HttpClient();
            var response = await client.GetAsync("http://localhost:5202/api/response/25");
             var response = await _clientPolicy.LinearHttpRetry.ExecuteAsync( () =>
             client.GetAsync("http://localhost:5202/api/response/25")
             );
            if(response.IsSuccessStatusCode)
            {
               Console.WriteLine("--> Response Service Retuned Success");
               return Ok();
            }
            Console.WriteLine("--> Response Service Retuned Failure");
            return StatusCode(StatusCodes.Status500InternalServerError);
        }
    }
}

可以運(yùn)行請(qǐng)求服務(wù)并在 Postman 中驗(yàn)證。此時(shí)我們會(huì)從響應(yīng)服務(wù)中得到失敗消息,因?yàn)檫€未實(shí)現(xiàn)重試機(jī)制。

使用 Polly 實(shí)現(xiàn)重試機(jī)制

使用 dotnet cli 運(yùn)行以下命令將 Polly 包添加到請(qǐng)求服務(wù)中:

dotnet add package Microsoft.Extensions.Http.Polly

創(chuàng)建一個(gè)名為 Policies 的文件夾,并添加 ClientPolicy 類文件,代碼如下:

using Polly;
using Polly.Retry;

namespace RequestService.Policies
{
    public class ClientPolicy
    {
        public AsyncRetryPolicy<HttpResponseMessage> ImmediateHttpRetry {get;}
        public AsyncRetryPolicy<HttpResponseMessage> LinearHttpRetry  {get;}
        public AsyncRetryPolicy<HttpResponseMessage> ExponentialHttpRetry  {get;}

        public ClientPolicy()
        {
            ImmediateHttpRetry = Policy.HandleResult<HttpResponseMessage>
            ( res => !res.IsSuccessStatusCode).RetryAsync(5);

            LinearHttpRetry = Policy.HandleResult<HttpResponseMessage>
            ( res => !res.IsSuccessStatusCode).
            WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(3));

            ExponentialHttpRetry = Policy.HandleResult<HttpResponseMessage>
            ( res => !res.IsSuccessStatusCode).
            WaitAndRetryAsync(5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,retryAttempt)));
        }
    }
}

在上述代碼中,我們?cè)跇?gòu)造函數(shù)中初始化了不同的重試策略。以 LinearHttpRetry 為例,若返回結(jié)果不是 SuccessStatusCode,則 WaitAndRetryAsync 方法會(huì)重試 5 次,每次間隔 3 秒。

接著,我們?cè)?Program.cs 中通過依賴注入配置 ClientPolicy:

builder.Services.AddSingleton<ClientPolicy> (new ClientPolicy());

然后在 RequestController 中使用 ClientPolicy:

private readonly ClientPolicy _clientPolicy;
private readonly IHttpClientFactory _clientFactory;

public RequestController(ClientPolicy clientPolicy, IHttpClientFactory clientFactory)
{
    _clientPolicy = clientPolicy;
    _clientFactory = clientFactory;
}

[HttpGet]
public async Task<ActionResult> MakeRequestNormalHttpClient()
{
    var client = new HttpClient();
    var response = await _clientPolicy.LinearHttpRetry.ExecuteAsync(() =>
        client.GetAsync("http://localhost:5202/api/response/25")
    );

    if(response.IsSuccessStatusCode)
    {
        Console.WriteLine("--> Response Service Retuned Success");
        return Ok();
    }
    Console.WriteLine("--> Response Service Retuned Failure");
    return StatusCode(StatusCodes.Status500InternalServerError);
}

為了更好地管理策略,可以在 Program.cs 中為命名的 HttpClient 添加策略:

builder.Services.AddHttpClient("Test")
    .AddPolicyHandler(request =>
        request.Method == HttpMethod.Get ?
        new ClientPolicy().LinearHttpRetry :
        new ClientPolicy().LinearHttpRetry
    );

在控制器中使用命名的 HttpClient:

public async Task<ActionResult> MakeRequest()
{
    var client = _clientFactory.CreateClient("Test");
    var response = await client.GetAsync("http://localhost:5202/api/response/25");

    if (response.IsSuccessStatusCode)
    {
        Console.WriteLine("--> Response Service Returned Success");
        return Ok();
    }
    Console.WriteLine("--> Response Service Returned Failure");
    return StatusCode(StatusCodes.Status500InternalServerError);
}

由于我們?cè)?Program.cs 中為命名的 Http 客戶端配置了策略,因此可以直接使用 IHttpClientFactory 來創(chuàng)建客戶端,并且策略已經(jīng)啟用。讓我們運(yùn)行代碼并在 Postman 中測(cè)試 LinearHttpRetry 策略。

在 Postman 中,我們成功地測(cè)試了線性等待策略。

圖片圖片

從響應(yīng)服務(wù)的調(diào)試信息中可以看到,在獲得成功響應(yīng)之前經(jīng)歷了四次失敗。

圖片圖片

在本文中,我們使用 Polly 實(shí)現(xiàn)了重試策略。除此之外,Polly 還提供其他模式,比如斷路器模式。

以上就是本文的全部?jī)?nèi)容,如有問題請(qǐng)留言。

譯文地址:c-sharpcorner.com/article/handling-transient-failures-in-net-8-with-polly

責(zé)任編輯:武曉燕 來源: DotNet開發(fā)跳槽
相關(guān)推薦

2022-01-02 08:43:46

Python

2009-07-20 16:45:41

使用StringBuiASP.NET

2024-02-04 09:08:00

Autofac容器.NET

2009-05-05 14:02:14

PlaceHolder控件ASP.NET

2019-12-31 09:56:16

Linux 系統(tǒng) 數(shù)據(jù)

2019-04-01 10:43:59

Linux問題故障

2024-02-05 13:07:00

.NETTable組件

2023-03-29 07:45:58

VS編輯區(qū)編程工具

2021-12-24 11:25:37

FreeDOS批處理文件Linux

2023-04-21 08:11:54

KubernetesPod

2024-03-15 15:15:53

.NETCPU系統(tǒng)

2011-09-07 09:51:27

Javascript

2022-02-25 11:16:51

故障運(yùn)維Nginx

2011-01-24 13:44:16

PING TCPIP Windows網(wǎng)

2019-04-26 13:25:06

服務(wù)器開發(fā)工具

2021-05-09 09:06:24

Python批處理命令

2024-09-18 05:10:00

.NETQuartz.NET框架

2021-10-18 10:54:48

.NET內(nèi)存管理

2021-06-01 05:51:55

ASP.NET Cor項(xiàng)目NuGet

2011-07-04 16:28:43

Windows XP故
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)