Building Resilient .NET Applications with Polly
Building Resilient .NET Applications with Polly
https://jdaniel1987.github.io/PollyResilience
https://github.com/fanqingsong/ResilienceExample
这是一篇为您整理的关于 Polly 库的技术博客文章,旨在帮助 .NET 开发者构建更具弹性的应用程序。
🛡️ 构建弹性 .NET 应用:Polly 库实战指南
在分布式系统中,网络中断、服务过载等瞬时故障是不可避免的。如果处理不当,这些微小的故障可能会导致整个系统的雪崩。
Polly 是一个强大的 .NET 库,专为帮助开发者优雅地处理这些瞬时故障而设计。通过 Polly,你可以轻松实现重试 (Retry)、熔断 (Circuit Breaker)、超时 (Timeout) 和回退 (Fallback) 等弹性模式,确保你的应用程序在面对故障时依然稳健。
💡 为什么要使用 Polly?
在微服务架构中,服务之间的调用充满了不确定性。Polly 通过以下方式帮助你缓解这些问题:
- 自动重试:当请求因瞬时故障失败时,自动重新发起请求。
- 熔断机制:当失败率达到阈值时,暂时切断请求,防止系统被拖垮。
- 超时控制:避免请求无限期挂起,释放系统资源。
- 降级回退:当主服务不可用时,提供备用方案(如返回默认值),保证核心功能可用。
🛠️ Polly 的核心弹性模式
Polly 提供了多种策略来应对不同的故障场景。以下是几种最常用的模式及其代码实现。
1. 重试策略
重试策略会在操作失败时自动重试指定的次数。这对于处理网络抖动非常有效。
以下代码展示了如何配置一个指数退避的重试策略:
var retryPolicy = Policy
.Handle<HttpRequestException>() // 定义需要处理的异常类型
.WaitAndRetryAsync(
retryCount: 3, // 重试次数
sleepDurationProvider: retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)), // 指数退避算法
onRetry: (exception, timeSpan, retryCount, context) =>
{
Console.WriteLine($"第 {retryCount} 次重试将在 {timeSpan} 后执行。错误: {exception.Message}\n");
});
执行策略:
await retryPolicy.ExecuteAsync(async () =>
{
// 执行具体的业务逻辑,例如 HTTP 请求
});
2. 熔断策略
熔断器就像电路中的保险丝。当失败次数达到一定阈值时,它会“跳闸”,在一段时间内直接拒绝所有请求,给系统一个恢复的窗口期。
var circuitBreakerPolicy = Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: 2, // 允许 2 次异常后熔断
durationOfBreak: TimeSpan.FromSeconds(10), // 熔断持续 10 秒
onBreak: (exception, timespan) => Console.WriteLine("⚡ 电路已断开 10 秒!"),
onReset: () => Console.WriteLine("✅ 电路已重置!\n"));
使用熔断器:
try
{
await circuitBreakerPolicy.ExecuteAsync(async () =>
{
// 执行具体的业务逻辑
});
}
catch(Polly.CircuitBreaker.BrokenCircuitException)
{
Console.WriteLine("电路处于断开状态,未执行操作。");
Console.WriteLine("等待电路闭合...\n");
}
3. 超时策略
防止某个操作因为响应过慢而耗尽系统资源。
var timeoutPolicy = Policy
.TimeoutAsync(
seconds: 5, // 设置 5 秒超时
timeoutStrategy: TimeoutStrategy.Pessimistic);
执行超时策略:
try
{
await timeoutPolicy.ExecuteAsync(async () =>
{
// 执行可能超时的操作
});
}
catch(TimeoutRejectedException)
{
Console.WriteLine("操作超时。");
}
4. 回退策略
当所有其他策略都失败时,回退策略充当“安全网”。它可以返回一个默认值,或者执行一个备用的逻辑。
var fallbackPolicy = Policy
.Handle<HttpRequestException>()
.FallbackAsync(
async (cancellationToken) =>
{
Console.WriteLine("🛡️ 回退策略:因故障执行备用操作。\n");
await Task.Delay(1000, cancellationToken);
return;
}
);
执行回退策略:
await fallbackPolicy.ExecuteAsync(async () =>
{
// 执行主业务逻辑
});
🔗 策略组合
在复杂的场景中,单一的策略往往不够用。Polly 允许你将多个策略组合在一起,形成一个强大的“策略包装器”。
组合示例:
var resiliencePolicy = Policy.WrapAsync(
retryPolicy,
circuitBreakerPolicy,
timeoutPolicy,
fallbackPolicy);
注意: 策略的执行顺序非常重要。通常建议的顺序是:重试 -> 熔断 -> 超时 -> 回退。
🚀 实战:在 HttpClientFactory 中集成 Polly
在 .NET Core 及更高版本中,Polly 可以与 HttpClientFactory 无缝集成。这是在实际项目中最推荐的用法。
配置示例:
services.AddHttpClient("ResilientClient")
.AddPolicyHandler(Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt)))
.AddPolicyHandler(Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(2, TimeSpan.FromMinutes(1)));
通过这种方式,所有使用名为 "ResilientClient" 的 HttpClient 发出的请求都会自动应用重试和熔断策略。
📌 总结
使用 Polly 能为你的 .NET 应用带来显著的好处:
- 提升弹性:优雅地处理故障,避免影响用户体验。
- 高度灵活:可以根据具体需求组合不同的策略。
- 易于使用:提供流畅的 API,配置直观。
- 生态兼容:与现代 .NET 工具(如
HttpClientFactory)完美配合。
Polly 是构建可靠、容错性强的 .NET 应用不可或缺的工具。立即在你的项目中集成 Polly,让弹性成为你系统的核心特性吧!

浙公网安备 33010602011771号