我有一个.NET 8 API,使用Polly来恢复Azure SQL和Microsoft Curve等外部服务的弹性.我当前的实现使用自定义再试和断路器策略,如下所示:
PollyExtensions.cs:
public static class PollyExtensions
{
public static AsyncRetryPolicy CreateRetryPolicy(this ILogger logger, string infraService)
{
var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);
return Policy
.Handle<SqlException>()
.Or<Exception>()
.Or<TimeoutException>()
.WaitAndRetryAsync(delay,
onRetry: (exception, timespan, retryAttempt, context) =>
{
logger.LogWarning(exception, "Error talking to {infraService}, Error: {Message}, will retry after {timeSpan}. Retry attempt {retryCount} ",
infraService, exception.Message, timespan, retryAttempt);
});
}
public static AsyncCircuitBreakerPolicy CreateCircuitBreakerPolicy()
{
return Policy
.Handle<Exception>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 5,
durationOfBreak: TimeSpan.FromMinutes(1)
);
}
}
在探索.NET 8中的新功能时,我发现了实现弹性的AddStandardResilienceHandler
和AddStandardHedgingHandler
.
References :
https://devblogs.microsoft.com/dotnet/building-resilient-cloud-services-with-dotnet-8/
https://juliocasal.com/blog/Building-Microservices-With-Dotnet-8
有人可以提供代码示例来演示如何在我的GraphSvcClient类的上下文中使用AddStandardResilienceeds和AddStandardHedgingeeds来进行外部依赖项调用?
与自定义策略相比,使用这些新功能时是否有任何具体的注意事项?
GraphSvcClient.cs
public sealed class GraphSvcClient(ICacheProvider cacheProvider,
IAzureAuthTokenService azureAuthTokenService,
ILogger<GraphSvcClient> logger) : IGraphSvcClient
{
private readonly ICacheProvider _cacheProvider = cacheProvider.IsNotNull();
private readonly IAzureAuthTokenService _azureAuthTokenService = azureAuthTokenService.IsNotNull();
private readonly ILogger<GraphSvcClient> _logger = logger.IsNotNull();
/// <summary>
/// Get Microsoft Graph graphClient
/// </summary>
/// <returns></returns>
public async Task<GraphServiceClient> GetGraphServiceClientAsync()
{
var accessToken = await GetAccessTokenAsync();
var retryPolicy = _logger.CreateRetryPolicy(infraService: "MicrosoftGraph");
var circuitBreakerPolicy = PollyExtensions.CreateCircuitBreakerPolicy();
var combinedPolicy = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);
var graphServiceClient = await combinedPolicy.ExecuteAsync(async () =>
{
var client = new GraphServiceClient(new DelegateAuthenticationProvider(async (req) =>
{
req.Headers.Authorization = new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme, accessToken);
await Task.CompletedTask;
}));
return client;
});
return graphServiceClient;
}
}
我正在考虑将Polly及其相关的nuget包更新到最新的兼容版本,以利用.NET 8中的最新功能.
项目中使用的Nuget包列表:
<PackageReference Include="Polly" Version="7.2.4" />
<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.0" />