Microsoft.Extensions.Http.Resilience 套件 是微軟新推出的套件(使用到 Polly),使我們能夠更穩定的呼叫 API ,在遇到網路問題或服務錯誤時能夠適當的重試。版本號從 8.0.0 開始,可以使用以下指令安裝:
下面是一個完整的 API 呼叫重試示範
上面的用法不算太難,但是有點冗長。如果使用 ASP.NET Core 的話可以在 Program.cs 中註冊就好了:
這裡偷懶一點,直接在 Controller 中使用:
註: 在 ASP.NET Core 中可以使用 IHttpClientFactory 來代替直接實例化 HttpClient
參考資料:
Microsoft.Learn - Build resilient HTTP apps: Key development patterns
dotnet add package Microsoft.Extensions.Http.Resilience
下面是一個完整的 API 呼叫重試示範
var httpClient = new HttpClient();
var pipeline = new ResiliencePipelineBuilder()
.AddRetry(new RetryStrategyOptions()
{
MaxRetryAttempts = 3, // 最大重試次數(共 4 次)
Delay = TimeSpan.FromSeconds(3), // 每次重試延遲
BackoffType = DelayBackoffType.Constant, // 每次重試的延遲方式(每次相同延遲
UseJitter = true, // 抖動(隨機延遲)
ShouldHandle = new PredicateBuilder()
.Handle<HttpRequestException>(), // 要處理的例外
OnRetry = retryArguments => // 重試時的處理
{
Console.WriteLine($"Retry {retryArguments.AttemptNumber} times");
Console.WriteLine($"Exception: {retryArguments.Outcome.Exception}");
return ValueTask.CompletedTask;
},
})
.AddTimeout(TimeSpan.FromSeconds(30)) // API 超時時間
.Build();
var response = await pipeline.ExecuteAsync(async cancellationToken =>
{
return await httpClient.GetAsync(url, cancellationToken); // 發起 API 請求
}
);
var content = await response.Content.ReadAsStringAsync();
上面的用法不算太難,但是有點冗長。如果使用 ASP.NET Core 的話可以在 Program.cs 中註冊就好了:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddResiliencePipeline("default", pipeline => // 重試策略名稱
{
pipeline
.AddRetry(new RetryStrategyOptions()
{
MaxRetryAttempts = 3, // 最大重試次數(共 4 次)
Delay = TimeSpan.FromSeconds(3), // 每次重試延遲
BackoffType = DelayBackoffType.Constant, // 每次重試的延遲方式(每次相同延遲
UseJitter = true, // 抖動(隨機延遲)
ShouldHandle = new PredicateBuilder()
.Handle<HttpRequestException>(), // 要處理的例外
OnRetry = retryArguments => // 重試時的處理
{
Console.WriteLine($"Retry {retryArguments.AttemptNumber} times");
Console.WriteLine($"Exception: {retryArguments.Outcome.Exception}");
return ValueTask.CompletedTask;
},
})
.AddTimeout(TimeSpan.FromSeconds(30)); // API 超時時間
});
var app = builder.Build();
這裡偷懶一點,直接在 Controller 中使用:
[ApiController]
[Route("[controller]")]
public class TestController(ResiliencePipelineProvider<string> pipelineProvider) : ControllerBase
{
[HttpGet]
public async Task<IActionResult> Get()
{
string url = "http://localhost:3000/users";
var httpClient = new HttpClient();
var pipeline = pipelineProvider.GetPipeline("default"); // 重試策略名稱
var response = await pipeline.ExecuteAsync(async cancellationToken =>
{
return await httpClient.GetAsync(url, cancellationToken); // 發起 API 請求
}
);
if (response.StatusCode != HttpStatusCode.OK)
return StatusCode((int)response.StatusCode, response.ReasonPhrase);
var content = await response.Content.ReadAsStringAsync();
return Ok(content);
}
註: 在 ASP.NET Core 中可以使用 IHttpClientFactory 來代替直接實例化 HttpClient
參考資料:
Microsoft.Learn - Build resilient HTTP apps: Key development patterns
感謝教學~
回覆刪除