استفاده از Polly برای مدیریت خطاهای موقتی در ASP.NET Core
نویسنده: محمد شریفی
تاریخ: ۱۴۰۳/۱۰/۲۰ ۱۹:۵۵
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
dotnet add package Polly
services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(2))); // Retry 3 times with a 2 second delayservices.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30))); // Circuit breaker after 3 failures for 30 secondsservices.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10))); // Timeout after 10 secondsservices.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.FallbackAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("Fallback data") }));public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("MyHttpClient")
.AddTransientHttpErrorPolicy(policyBuilder =>
policyBuilder.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2))) // Retry 3 times with a 2 second delay
.AddTransientHttpErrorPolicy(policyBuilder =>
policyBuilder.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30))); // Circuit breaker after 3 failures for 30 seconds
}services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.WrapAsync(
Policy.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2)), // Retry Policy
Policy.Handle<HttpRequestException>()
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30)), // Circuit Breaker Policy
Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(10)))); // Timeout Policyservices.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.BulkheadAsync<HttpResponseMessage>(maxParallelRequests: 10));public void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient("MyHttpClient")
.AddTransientHttpErrorPolicy(policy => policy.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2)))
.AddTransientHttpErrorPolicy(policy => policy.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30)));
}services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.RequestTimeout)
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(5)));services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, attempt =>
{
_logger.LogWarning("Retry attempt #{Attempt}", attempt);
return TimeSpan.FromSeconds(2);
}));services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.WaitAndRetryAsync(5, attempt =>
TimeSpan.FromSeconds(Math.Pow(2, attempt)))); // Exponential backoffservices.AddHttpClient("MyHttpClient")
.AddPolicyHandler(Policy.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.RequestTimeout)
.WaitAndRetryAsync(5, _ => TimeSpan.FromSeconds(2)));var cacheProvider = new MemoryCacheProvider(new MemoryCache(new MemoryCacheOptions()));
var cachePolicy = Policy.CacheAsync<HttpResponseMessage>(
cacheProvider.AsyncFor<HttpResponseMessage>(),
TimeSpan.FromMinutes(5));
services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(cachePolicy);var rateLimitPolicy = Policy.RateLimitAsync(10, TimeSpan.FromSeconds(1));
services.AddHttpClient("MyHttpClient")
.AddPolicyHandler(rateLimitPolicy);public class MyApiService
{
private readonly HttpClient _httpClient;
private readonly ILogger<MyApiService> _logger;
public MyApiService(IHttpClientFactory httpClientFactory, ILogger<MyApiService> logger)
{
_httpClient = httpClientFactory.CreateClient("MyHttpClient");
_logger = logger;
}
public async Task<string> GetApiDataAsync()
{
try
{
var response = await _httpClient.GetAsync("https://api.example.com/data");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error occurred while calling the API.");
throw;
}
}
}dotnet add package Polly.Core
using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;
public class PollyExample
{
public static async Task Main(string[] args)
{
// Define the Retry strategy
var retryStrategy = new ResilienceStrategyBuilder()
.AddRetry(3)
.Build();
// Define the Timeout strategy
var timeoutStrategy = new ResilienceStrategyBuilder()
.AddTimeout(TimeSpan.FromSeconds(5))
.Build();
// Combine the strategies into a resilience pipeline
var resiliencePipeline = new ResiliencePipelineBuilder()
.AddStrategy(retryStrategy)
.AddStrategy(timeoutStrategy)
.Build();
// Execute the HTTP request using the resilience pipeline
var response = await resiliencePipeline.ExecuteAsync(async () =>
{
var httpClient = new HttpClient();
return await httpClient.GetAsync("http://example.com");
});
Console.WriteLine($"Response Status Code: {response.StatusCode}");
}
}var retryStrategy = new ResilienceStrategyBuilder()
.AddRetry(3)
.Build();var timeoutStrategy = new ResilienceStrategyBuilder()
.AddTimeout(TimeSpan.FromSeconds(5))
.Build();var resiliencePipeline = new ResiliencePipelineBuilder()
.AddStrategy(retryStrategy)
.AddStrategy(timeoutStrategy)
.Build();var response = await resiliencePipeline.ExecuteAsync(async () =>
{
var httpClient = new HttpClient();
return await httpClient.GetAsync("http://example.com");
});dotnet add package Polly --version 8.x.x