.NET Core 微服务之Polly重试策略
接着上一篇说,正好也是最近项目里用到了,正好拿过来整理一下,园子里也有一些文章介绍比我详细。
简单介绍一下绍轻量的故障处理库 Polly Polly是一个.NET弹性和瞬态故障处理库
允许我们以非常顺畅和线程安全的方式来执行诸如重试、断路器、超时、隔离、缓存、后退等策略, 能为我们在微服务架构提供更稳定的服务。当然,目前的 Service Mesh 显得更高大上,而且更强大,它更偏向从运维层面解决以上问题,不过这还是的看具体项目中怎么去使用和决定了。
在微服务架构下,我们可能会遇到类似以下问题:
- 某些接口异常,最终造成应用程序池奔溃;
- 某些接口不稳定、偶尔超时,数据获取异常;
- 某些服务不稳定,调用方连接不上;
- 某些服务异常,最终主服务挂掉(雪崩效应);
当然在实际情况下,我们可能只需要确保提供给用户的服务是可用状态,不出现 “Service Unavailable” 这样的画面就好。至于接口偶尔异常,可能对某些类型的项目来说并不太关键,用户可能通过重新请求、刷新页面就可以解决,当然我们还可以在代码层面做兼容,满满的try/catch、for/while 循环解决重试来保证更高的可靠性。
这个时候Polly就能很好的起来作用,Polly 的使用相对比较简单,当然还是得看项目结构。我们的主项目在调用微服务接口时使用了AOP,类似这种情况下,所以调用微服务的接口都是统一入口,所以我们只需要在AOP内加上 Polly 的一些策略,其他代码不用做任何修改,就可以解决一些问题了。
安装#
Install-Package Polly
使用步骤说明#
- 定义策略
- 执行方法
可以看一下代码,我们项目主要使用的是Grpc这个框架,其他的微服务框架,使用起来大致差不多
public void Intercept(IInvocation invocation) { // some code try { // 创建一个策略,如果 invocation.Proceed 的执行出现 Grpc.Core.RpcException 异常,并且 StatusCode == Grpc.Core.StatusCode.Unavailable,则重试一次 var policy = Policy .Handle<Grpc.Core.RpcException>(t => t.Status.StatusCode == Grpc.Core.StatusCode.Unavailable) .Retry(); // 默认一次 // 将策略应用到 invocation.Proceed 方法上 policy.Execute(invocation.Proceed); } catch (Exception ex) { // some code Console.WriteLine($"{ ex.Message},{ex.StackTrace}"); } }
策略条件定义#
策略的执行需要依赖于条件,Polly 支持对异常与结果进行策略条件定义。
异常
// 指定某个异常 Policy .Handle<SomeExceptionType>(); // 指定某个异常条件 Policy .Handle<SomeExceptionType>(ex => ex.xxx == "xxx") // 指定多个异常 Policy .Handle<SomeExceptionType1>() .Or<SomeExceptionType2>() // 指定多个可能异常条件 Policy .Handle<SomeExceptionType1>(ex => ex.xxx1 == "xxx") .Or<SomeExceptionType2>(ex => ex.xxx2 == "xxx")
返回结果
// 指定某个结果 Policy .HandleResult<ResponseMessage>(r => r.xxx == "xxx") // 指定多个可能的结果 Policy .HandleResult<ResponseMessage>(r => r.xxx1 == "xxx") .OrResult<ResponseMessage>(r => r.xxx2 == "xxx")
重试策略(Retry )#
// 指定异常下重试一次 Policy .Handle<SomeExceptionType>() .Retry(); // 指定异常下重试3次 Policy .Handle<SomeExceptionType>() .Retry(3); // 指定异常下无限重试 Policy .Handle<SomeExceptionType>() .RetryForever(); // 每次重试之间等待指定的时间间隔 Policy .Handle<SomeExceptionType>() .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(7) });
Retry 可以指定一个要执行的 Action。Action 参数:exception 当前异常信息,retryCount 当前执行第几次,context 当前执行上下文信息。
测试一下:
private static int times = 0; public static void TestPolicy() { var policy = Policy .Handle<Exception>() .Retry(3, (exception, retryCount, context) => // 出异常会执行以下代码 { Console.WriteLine($"exception:{ exception.Message}, retryCount:{retryCount}, id:{context["id"]}, name:{context["name"]}"); }); try { // 通过 new Context 传递上下文信息 var result = policy.Execute(Test, new Context("data", new Dictionary<string, object>() { { "id", "1" }, { "name", "beck" } })); Console.WriteLine($"result:{result}"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } private static string Test() { // 每执行一次加1 times++; // 前2次都抛异常 if (times < 3) { throw new Exception("exception message"); } return "success"; }
测试结果:
可以看到得到了咱们想要的效果,具体项目可以具体去实施,下一篇咱们接着说Polly的熔断策略。感兴趣可以自行搜索Polly的相关文档看看。
参考链接#
没有彩蛋
作者:DanielYao
出处:https://www.cnblogs.com/DanielYao/p/11086574.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
欢迎大家关注我的微信公众号,新文章会优先发到公众号!
本文来自博客园,作者:打滚的姚先森,转载请注明原文链接:https://www.cnblogs.com/DanielYao/p/11086574.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异