Polly简单使用
简介
Polly 是一个针对 .NET 应用程序的库,提供了一系列经过优化的故障处理策略,帮助开发人员实现重试、断路器、超时和熔断机制等。通过 Polly 库,开发人员可以更容易地编写鲁棒性更强、更可靠的应用程序。
Retry 策略
当出现异常或错误时,自动重试指定次数。
static void Main()
{
try
{
//捕获DivideByZeroException异常会重试三次
var retryTwoTimesPolicy =
Policy
//处理多个异常类型通过OR即可
.Handle<DivideByZeroException>().Or<ArgumentException>()
.Retry(3, (ex, count) =>
{
Console.WriteLine("执行失败! 重试次数 {0}", count);
Console.WriteLine("异常来自 {0}", ex.GetType().Name);
});
retryTwoTimesPolicy.Execute(() =>
{
var a = 0;
return 1 / a;
});
}
catch (Exception ex)
{
//第四次异常不做处理,抛出异常
Console.WriteLine($"catch {ex.GetType().Name}");
}
finally
{
Console.WriteLine($"finally");
}
}
static void Main()
{
try
{
//捕获DivideByZeroException异常会重试三次
var retryTwoTimesPolicy =
Policy
//处理多个异常类型通过OR即可
.Handle<DivideByZeroException>().Or<ArgumentException>()
//添加重新间隔
.WaitAndRetry(new[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(3),
TimeSpan.FromSeconds(5),
}, (ex, TimeSpan) =>
{
Console.WriteLine($"执行失败! 执行间隔 {TimeSpan} {DateTime.Now}");
Console.WriteLine($"异常来自 {ex.GetType().Name}");
});
retryTwoTimesPolicy.Execute(() =>
{
var a = 0;
return 1 / a;
});
}
catch (Exception ex)
{
Console.WriteLine($"catch {ex.GetType().Name}");
}
finally
{
Console.WriteLine($"finally");
}
}
Timeout 策略
在规定时间内未获取到响应时,自动取消请求并抛出超时异常。
static async Task Main()
{
// 创建超时策略,等待最多 1 秒钟
// 如果在等待时间内未完成操作,则会抛出 TimeoutRejectedException 异常。
var timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromSeconds(1), TimeoutStrategy.Pessimistic);
try
{
// 在超时策略中执行操作
await timeoutPolicy.ExecuteAsync(async (ct) =>
{
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("https://www.example.com", ct);
// 处理响应结果
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync(ct);
Console.WriteLine(content);
}
}, CancellationToken.None);
/*
* 最后,我们使用 ExecuteAsync 方法,在组合策略中执行异步操作,并在 CancellationToken 参数中传递 CancellationToken.None 来允许取消操作。
* 如果在指定的等待时间内没有得到响应,则会抛出 TimeoutRejectedException 异常。如果操作失败,则会捕获异常并输出相应的信息。
*/
}
catch (TimeoutRejectedException)
{
Console.WriteLine("The operation timed out.");
}
catch (Exception ex)
{
Console.WriteLine($"Exception caught: {ex.GetType().Name}");
}
}
Circuit Breaker 策略
当某个远程服务发生异常或错误时,自动跳闸断路,避免进一步请求对该服务造成负载压力和损害。
static async Task Main()
{
//连续失败 5 次,那么断路器会被打开,并保持 5 秒钟的打开状态时间,防止继续执行相同的操作
var circuitBreakerPolicy = Policy
.Handle<Exception>()
.CircuitBreaker(5, TimeSpan.FromSeconds(5));
// 对多个操作使用相同的断路器策略
for (int i = 0; i < 20; i++)
{
try
{
await Task.Delay(TimeSpan.FromSeconds(1));
// 尝试执行某些可能会抛出异常的操作
circuitBreakerPolicy.Execute(() =>
{
// TODO: 执行某些操作,可能会抛出异常
throw new Exception($"异常");
});
}
catch (Exception ex)
{
// 断路器开启,操作被拒绝
Console.WriteLine($"time:{DateTime.Now} Num:{i} failed: {ex.Message}");
}
}
}
Microsoft.Extensions.Http.Polly
是基于 Polly 的一个 ASP.NET Core HttpClient 工厂的扩展库,它能够为应用程序提供简单易用的、可扩展的 HTTP 客户端工厂,并且可以很容易地实现重试、熔断、超时等策略。
var retryPolicy = HttpPolicyExtensions
.HandleTransientHttpError()
.Or<TimeoutRejectedException>() // thrown by Polly's TimeoutPolicy if the inner execution times out
.RetryAsync(3);
var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10);
//更方便的使用polliy
services.AddHttpClient("example.com", c => c.BaseAddress = new Uri("http://example.com"))
.AddPolicyHandler(retryPolicy)
.AddPolicyHandler(timeoutPolicy);
参考
https://github.com/App-vNext/Polly
https://github.com/App-vNext/Polly.Extensions.Http/blob/master/README.md
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫