.NET 使用 Polly 实现容错与重试机制:完整示例教程

在构建分布式系统或微服务架构时,面对网络波动、超时或服务不可用等瞬态故障是常见的挑战。为提高系统的稳定性和可靠性,.NET 提供了 Polly 库,允许开发者定义重试、断路器、超时等容错策略。本文将通过具体示例,演示如何在 .NET 应用中使用 Polly 实现这些策略。

.NET 使用 Polly 实现容错与重试机制:完整示例教程

1. 安装 Polly 库

首先,使用 NuGet 包管理器安装 Polly 库:

dotnet add package Polly

2. Polly 重试策略示例

重试策略用于在请求失败时自动重试,适用于网络波动等瞬态故障场景。

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var httpClient = new HttpClient();
        var retryPolicy = Policy
            .Handle<HttpRequestException>()
            .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

        await retryPolicy.ExecuteAsync(async () =>
        {
            var response = await httpClient.GetAsync("https://example.com");
            response.EnsureSuccessStatusCode();
            Console.WriteLine("Request succeeded.");
        });
    }
}

在上述示例中,WaitAndRetryAsync 方法定义了一个指数退避的重试策略,最多重试 3 次,每次重试的间隔时间呈指数增长。

3. Polly 断路器策略示例

断路器策略用于在连续失败达到一定阈值时,暂时中断请求,防止系统被故障请求淹没。

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var httpClient = new HttpClient();
        var circuitBreakerPolicy = Policy
            .Handle<HttpRequestException>()
            .CircuitBreakerAsync(2, TimeSpan.FromSeconds(30));

        for (int i = 0; i < 5; i++)
        {
            try
            {
                await circuitBreakerPolicy.ExecuteAsync(async () =>
                {
                    var response = await httpClient.GetAsync("https://example.com");
                    response.EnsureSuccessStatusCode();
                    Console.WriteLine("Request succeeded.");
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Request failed: {ex.Message}");
            }
        }
    }
}

在这个示例中,CircuitBreakerAsync 方法定义了一个断路器策略,当连续 2 次请求失败时,断路器会在 30 秒内打开,期间所有请求都会被拒绝。

4. Polly 超时策略示例

超时策略用于限制请求的最大执行时间,防止请求长时间挂起。

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var httpClient = new HttpClient();
        var timeoutPolicy = Policy
            .TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(5));

        try
        {
            var response = await timeoutPolicy.ExecuteAsync(() =>
                httpClient.GetAsync("https://example.com"));
            response.EnsureSuccessStatusCode();
            Console.WriteLine("Request succeeded.");
        }
        catch (TimeoutRejectedException)
        {
            Console.WriteLine("Request timed out.");
        }
    }
}

在这个示例中,TimeoutAsync 方法定义了一个超时策略,限制请求的最大执行时间为 5 秒。

5. Polly 组合策略示例

Polly 允许将多个策略组合使用,以应对复杂的故障场景。

using Polly;
using System;
using System.Net.Http;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        var httpClient = new HttpClient();
        var retryPolicy = Policy
            .Handle<HttpRequestException>()
            .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));

        var circuitBreakerPolicy = Policy
            .Handle<HttpRequestException>()
            .CircuitBreakerAsync(2, TimeSpan.FromSeconds(30));

        var policyWrap = Policy.WrapAsync(retryPolicy, circuitBreakerPolicy);

        try
        {
            await policyWrap.ExecuteAsync(async () =>
            {
                var response = await httpClient.GetAsync("https://example.com");
                response.EnsureSuccessStatusCode();
                Console.WriteLine("Request succeeded.");
            });
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Request failed: {ex.Message}");
        }
    }
}

在这个示例中,WrapAsync 方法将重试策略和断路器策略组合在一起,确保在请求失败时,先进行重试,再根据断路器策略判断是否继续请求。

6. 最佳实践建议

  • 合理配置策略参数:根据实际业务需求,合理设置重试次数、超时时间等参数,避免过度重试或过短的超时时间。
  • 日志记录:在策略中添加日志记录,便于故障排查和性能分析。
  • 测试策略效果:在开发和测试环境中模拟故障,验证策略的有效性。
  • 避免策略滥用:对于非瞬态故障(如 4xx 错误),应避免使用重试策略,以免加重系统负担。

通过上述示例和最佳实践,你可以在 .NET 应用中有效地使用 Polly 库,实现重试、断路器、超时等容错策略,提升系统的稳定性和可靠性。

评论