Stay Hungry,Stay Foolish!

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 应用带来显著的好处:

  1. 提升弹性:优雅地处理故障,避免影响用户体验。
  2. 高度灵活:可以根据具体需求组合不同的策略。
  3. 易于使用:提供流畅的 API,配置直观。
  4. 生态兼容:与现代 .NET 工具(如 HttpClientFactory)完美配合。

Polly 是构建可靠、容错性强的 .NET 应用不可或缺的工具。立即在你的项目中集成 Polly,让弹性成为你系统的核心特性吧!

 

posted @ 2026-08-25 23:10  lightsong  阅读(4)  评论(0)    收藏  举报
千山鸟飞绝,万径人踪灭