在这篇文章中,我们将探讨如何在 C# 中使用 Polly 以及它如何帮助轻松处理故障和重试。Polly 是一个流行的 NuGet 包,提供了一组强大的工具和模式,可以极大地简化我们代码中的故障处理和重试机制。
通过在我们的代码中利用 Polly,我们可以处理各种类型的故障,比如网络错误或数据库连接失败。然后,我们可以实现智能的重试策略,以确保我们的应用在这些问题不可避免地发生时不会崩溃(请记住:墨菲定律)。Polly 提供了一种灵活且可配置的方式来处理这些情况,无论是需要处理瞬态故障还是简单地重试失败的操作。
我将向您展示三个有趣的代码示例,展示了在 C# 中使用 Polly 的不同用例 - 所以让我们开始吧!
1 – 在C#中使用Polly处理故障
在构建健壮可靠的应用程序时,有效地处理故障是很重要的。故障处理是指处理程序在执行过程中可能发生的错误、异常和故障的过程 - 我们将使用 C# 中的 Polly 来帮助我们完成这项任务。
为了演示 Polly 如何处理连接问题,让我们考虑一个场景,即我们的应用程序需要向外部 API 发出网络请求。我们希望确保在发生任何与连接相关的故障,如临时网络中断或间歇性故障时,请求会自动重试。
让我们看看如何在 C# 中使用 Polly 处理网络请求中的连接问题:
using Polly;
using Polly.Retry;
var handler = new NetworkRequestHandler();
var response = await handler.MakeNetworkRequestAsync("https://www.devleader.ca/sitemap.xml");
Console.WriteLine(#34;Response status code: {response.StatusCode}");
public class NetworkRequestHandler
{
private readonly HttpClient _httpClient;
private readonly AsyncRetryPolicy<HttpResponseMessage> _retryPolicy;
public NetworkRequestHandler()
{
_httpClient = new HttpClient();
// Define a retry policy: retry on HttpRequestException, 3 retries with exponential backoff
_retryPolicy = Policy
.HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
.Or<HttpRequestException>()
.WaitAndRetryAsync(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
onRetry: (outcome, timespan, retryAttempt, context) =>
{
Console.WriteLine(#34;Request failed with {outcome.Exception?.Message}. Waiting {timespan} before next retry. Retry attempt {retryAttempt}.");
});
}
public async Task<HttpResponseMessage> MakeNetworkRequestAsync(string requestUri)
{
return await _retryPolicy.ExecuteAsync(async () =>
{
Console.WriteLine(#34;Making request to {requestUri}");
var response = await _httpClient.GetAsync(requestUri);
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(#34;Request failed with status code: {response.StatusCode}");
throw new HttpRequestException(#34;Request to {requestUri} failed with status code {response.StatusCode}");
}
return response;
});
}
}
在上面的代码示例中,我们定义了一个 NetworkRequestHandler 类,该类封装了使用 .NET 框架中的 HttpClient 类进行网络请求的逻辑。我们使用 Polly 初始化了一个 AsyncRetryPolicy,其故障条件为 HttpRequestException 类型。这意味着每当抛出 HttpRequestException 时,该策略将被触发。
WaitAndRetry 方法用于指定重试尝试的次数以及每次重试之间的时间延迟。在这个例子中,我们重试请求 3 次,使用指数增加的延迟,公式为 TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))。
在 MakeNetworkRequest 方法中,我们使用 Polly 策略通过在策略上调用 Execute 方法来执行网络请求。如果在执行过程中发生 HttpRequestException,Polly 将根据定义的策略自动重试请求。
2 – 在C#中使用Polly的重试机制
在软件工程中,常常会遇到特定操作由于网络问题、资源限制或其他瞬态故障而暂时失败的情景。在这种情况下,通常会实现重试机制,以自动重试失败的操作一定次数,直到成功或达到最大重试次数为止。这有助于提高软件应用程序的可靠性和健壮性。
在C#中使用Polly简化重试机制:
在实现 C# 中的重试机制时,NuGet 包 Polly 可以提供帮助。Polly 是一个强大的库,为处理代码中的故障和重试提供了一种简单而优雅的方式。它通过将复杂的重试逻辑封装到一组可重用的策略中,简化了实现重试的过程。
使用Polly自动重试失败的数据库操作:
让我们考虑一种情况,我们需要执行一个数据库操作,比如将记录插入表中,但可能会出现暂时的连接问题或资源约束,导致操作失败。使用 Polly,我们可以通过应用重试策略轻松处理这种失败情况。
首先,我们需要通过在项目文件的依赖项部分添加以下行来安装 Polly NuGet 包:
<ItemGroup>
<PackageReference Include="Polly" Version="8.3.0" />
</ItemGroup>
安装了该包后,我们就可以开始使用 Polly 来实现重试机制了。以下是一个示例代码片段,演示了如何使用 Polly 自动重试失败的数据库操作:
using Polly;
using System.Data.SqlClient;
async Task<bool> InsertRecordAsync(Record record, CancellationToken cancellationToken)
{
int maxRetryCount = 3;
var connectionString = "// TODO: configure this elsewhere...";
var retryPolicy = Policy
.Handle<SqlException>() // Specify the type of exception to handle
.WaitAndRetryAsync(maxRetryCount, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt))); // Exponential backoff strategy
return await retryPolicy.ExecuteAsync(async ct =>
{
using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
using var command = connection.CreateCommand();
command.CommandText = "INSERT INTO Records (Id, Name) VALUES (@Id, @Name)";
command.Parameters.AddWithValue("@Id", record.Id);
command.Parameters.AddWithValue("@Name", record.Name);
try
{
// Perform the database operation
var result = await command.ExecuteNonQueryAsync(ct);
return result == 1;
}
catch (SqlException)
{
// Rethrow the exception to let Polly handle the retry logic
throw;
}
}, cancellationToken);
}
public sealed record Record(int Id, string Name);
在上面的示例中,我们使用 Policy.Handle<SqlException>() 方法定义了一个重试策略,以指定我们要处理的异常类型,这里是 SQL 异常。然后,我们使用 WaitAndRetryAsync 方法配置策略,以指定使用指数回退策略重试操作,每次重试尝试都会等待增加的时间,最多重试 maxRetryCount 次。
在 ExecuteAsync 方法中,我们将数据库操作封装在 try-catch 块中。如果由于 SQL 异常而导致操作失败,我们将抛出异常以让 Polly 处理重试逻辑。Polly 将根据定义的策略自动重试操作,提供了处理临时故障的无缝体验。
3 – 在C#中使用Polly进行高级重试和断路器模式
有时我们需要更高级的重试机制和断路器模式,以使我们的应用程序达到更高水平的弹性。幸运的是,C# 中的 Polly 库也为我们提供了这方面的支持!
当与外部服务或资源交互时,常常会遇到瞬态故障,如网络问题或服务不可用。Polly 允许我们定义自定义的重试策略,规定重试的次数以及重试之间的延迟。这确保了我们的应用程序能够优雅地处理临时故障,并提高系统的整体可靠性。
使用Polly定制重试策略
Polly 提供了灵活的选项,可以根据特定要求定制重试策略。我们可以定义重试次数、回退策略以确定重试之间的延迟,甚至可以定义一个断言,有选择地仅在特定异常发生时进行重试。通过定制这些策略,我们可以有效地处理不同的情景。
以下是一个示例,演示了如何使用 Polly 实现带有指数回退策略的重试策略:
var retryPolicy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(response => response.StatusCode == HttpStatusCode.InternalServerError)
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)))
;
在这个示例中,我们定义了一个重试策略,如果出现 HttpRequestException 或者 HttpResponseMessage 的状态代码为 InternalServerError,将最多重试 3 次。回退策略是指数的,重试之间的延迟会根据重试尝试次数呈指数增加。
在C#中使用Polly实现断路器模式
断路器模式在防止级联故障和保护系统免受对失败服务的大量重复请求方面发挥着重要作用。Polly 提供了内置支持,用于实现断路器模式,有助于自动管理断路器的状态并控制请求的流程。
要使用 Polly 实现断路器模式,我们需要定义失败和成功的阈值值,以及监视这些指标的时间窗口。一旦断路器触发,进一步的请求将被短路,防止对失败服务的不必要调用。
以下是如何使用 Polly 实现断路器模式的示例:
var circuitBreakerPolicy = Policy
.Handle<HttpRequestException>()
.OrResult<HttpResponseMessage>(response => response.StatusCode == HttpStatusCode.InternalServerError)
.CircuitBreakerAsync(3, TimeSpan.FromSeconds(30))
;
在这个示例中,断路器策略被配置为在 30 秒的窗口内连续出现 3 次故障时触发打开状态。一旦断路器打开,后续的请求将被自动拒绝,防止进一步的调用,直到指定的恢复期过去为止。
现在你知道如何在C#中使用Polly了!
你有了 3 个可用的代码示例,帮助你了解如何在 C# 中使用 Polly。通过 Polly 你可以轻松处理故障和重试,提高应用程序的可靠性和弹性。在这篇文章中,我们探讨了 Polly 的三种不同用例,涵盖了故障处理、基本重试和高级重试模式,比如断路器。
通过将 Polly 纳入你的项目,你可以提升软件的稳定性和响应性。通过使用策略来指定重试次数、持续时间和其他可配置的参数,你可以在面对故障时控制应用程序的行为和容错性。