今天介绍一个 .NET 开源库:Polly,它是支持 .NET Core 的,目前在 GitHub 的 Star 数量已经接近 5 千,它是一个强大且实用的 .NET 库。

Polly 介绍

官方对 Polly 的介绍是这样的:

Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.

翻译过来大概意思是:Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以 Fluent 和线程安全的方式来实现重试、断路、超时、隔离和回退策略。

这个描述有点抽象,我们一起来理解一下。

首先这里的说的瞬态故障包含了程序发生的异常和出现不符合开发者预期的结果。所谓瞬态故障,就是说故障不是必然会发生的,而是偶然可能会发生的,比如网络偶尔会突然出现不稳定或无法访问这种故障。至于弹性,就是指应对故障 Polly 的处理策略具有多样性和灵活性,它的各种策略可以灵活地定义和组合。

下面来演示一个例子,大家就更清楚了。

故障处理策略示例

安惯例,创建一个空的 Console 项目,和安装 NuGet 包:

Install-Package Polly

Polly 的异常处理策略的基本用法可以分为三个步骤,步骤说明包含在下面代码中:

static void Main(string[] args)
{Policy// 1. 指定要处理什么异常.Handle<HttpRequestException>()//    或者指定需要处理什么样的错误返回.OrResult<HttpResponseMessage>(r => r.StatusCode == HttpStatusCode.BadGateway)// 2. 指定重试次数和重试策略.Retry(3, (exception, retryCount, context) =>{Console.WriteLine($"开始第 {retryCount} 次重试:");})// 3. 执行具体任务.Execute(ExecuteMockRequest);Console.WriteLine("程序结束,按任意键退出。");Console.ReadKey();
}static HttpResponseMessage ExecuteMockRequest()
{// 模拟网络请求Console.WriteLine("正在执行网络请求...");Thread.Sleep(3000);// 模拟网络错误return new HttpResponseMessage(HttpStatusCode.BadGateway);
}

从例子中可以看到,Polly 的 API 支持流式(Fluent)调用,使用起来很方便。这个示例对错误处理的策略很简单,当发生请求异常或网络错误时,就重试 3 次。我们可以从下面的运行结果图看到这个策略的执行过程:

下面具体来看 Polly 支持的各种故障处理策略。

Polly 的七种策略

Polly 可以实现重试、断路、超时、隔离、回退和缓存策略,下面给出这些策略的应用场景说明和基本使用方法。

重试(Retry)

出现故障自动重试,这个是很常见的场景,上面也已经给出例子了,这里不再细述。

断路(Circuit-breaker)

当系统遇到严重问题时,快速回馈失败比让用户/调用者等待要好,限制系统出错的体量,有助于系统恢复。比如,当我们去调一个第三方的 API,有很长一段时间 API 都没有响应,可能对方服务器瘫痪了。如果我们的系统还不停地重试,不仅会加重系统的负担,还会可能导致系统其它任务受影响。所以,当系统出错的次数超过了指定的阈值,就要中断当前线路,等待一段时间后再继续。

下面是一个基本的断路策略的使用方式:

Policy.Handle<SomeException>().CircuitBreaker(2, TimeSpan.FromMinutes(1));

这句代码设定的策略是,当系统出现两次某个异常时,就停下来,等待 1 分钟后再继续。这是基本的用法,你还可以在断路时定义中断的回调和重启的回调。

超时(Timeout)

当系统超过一定时间的等待,我们就几乎可以判断不可能会有成功的结果。比如平时一个网络请求瞬间就完成了,如果有一次网络请求超过了 30 秒还没完成,我们就知道这次大概率是不会返回成功的结果了。因此,我们需要设置系统的超时时间,避免系统长时间做无谓的等待。

下面是超时策略的一个基本用法:

Policy.Timeout(30, onTimeout: (context, timespan, task) =>
{// do something
});

这里设置了超时时间不能超过 30 秒,否则就认为是错误的结果,并执行回调。

隔离(Bulkhead Isolation)

当系统的一处出现故障时,可能促发多个失败的调用,很容易耗尽主机的资源(如 CPU)。下游系统出现故障可能导致上游的故障的调用,甚至可能蔓延到导致系统崩溃。所以要将可控的操作限制在一个固定大小的资源池中,以隔离有潜在可能相互影响的操作。

下面是隔离策略的一个基本用法:

Policy.Bulkhead(12, context =>
{// do something
});

这个策略是最多允许 12 个线程并发执行,如果执行被拒绝,则执行回调。

回退(Fallback)

有些错误无法避免,就要有备用的方案。这个就像浏览器不支持一些新的 CSS 特性就要额外引用一个 polyfill 一样。一般情况,当无法避免的错误发生时,我们要有一个合理的返回来代替失败。

比如很常见的一个场景是,当用户没有上传头像时,我们就给他一个默认头像,这种策略可以这样定义:

Policy.Handle<Whatever>().Fallback<UserAvatar>(() => UserAvatar.GetRandomAvatar())

缓存(Cache)

一般我们会把频繁使用且不会怎么变化的资源缓存起来,以提高系统的响应速度。如果不对缓存资源的调用进行封装,那么我们调用的时候就要先判断缓存中有没有这个资源,有的话就从缓存返回,否则就从资源存储的地方(比如数据库)获取后缓存起来,再返回,而且有时还要考虑缓存过期和如何更新缓存的问题。Polly 提供了缓存策略的支持,使得问题变得简单。

var memoryCacheProvider = new MemoryCacheProvider(myMemoryCache);
var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5));
TResult result = cachePolicy.Execute(context => getFoo(), new Context("FooKey"));

这是官方的一个使用示例用法,它定义了缓存 5 分钟过期的策略,然后把这个策略应用在指定的 Key(即 FooKey)上。

这一块内容值得用一整篇的内容来讲,下次有机会再详细讲讲 Polly 的缓存策略。

策略包(Policy Wrap)

一种操作会有多种不同的故障,而不同的故障处理需要不同的策略。这些不同的策略必须包在一起,作为一个策略包,才能应用在同一种操作上。这就是文章开头说的 Polly 的弹性,即各种不同的策略能够灵活地组合起来。

策略包的基本用法是这样的:

var policyWrap = Policy.Wrap(fallback, cache, retry, breaker, timeout, bulkhead);
policyWrap.Execute(...);

先是把预先定义好的多种不同的策略包在一起,作为一个整体策略,然后应用在同一个操作上。

总结

本文先是对 Polly 做了一个简单介绍,通过一个例子让大家知道了 Polly 的基本用法和步骤,然后分别介绍了 Polly 的七种策略。其实 Polly 远比本文讲的要强大,但由于篇幅的限制和精力有限,只能笼统地给大家做个介绍,更多的应用场景还需要结合实际的例子才能讲清楚。要深入研究,可以前往查看 Polly 的 GitHub 主页和 Wiki 文档。

参考:

https://github.com/App-vNext/Polly

https://github.com/App-vNext/Polly/wiki

---------------------
作者:ahilll
来源:CSDN
原文:https://blog.csdn.net/ahilll/article/details/82908811
版权声明:本文为作者原创文章,转载请附上博文链接!

[转].NET 开源项目 Polly 介绍相关推荐

  1. .NET 开源项目 StreamJsonRpc 介绍[下篇]

    阅读本文大概需要 9 分钟. 大家好,这是 .NET 开源项目 StreamJsonRpc 介绍的最后一篇.上篇介绍了一些预备知识,包括 JSON-RPC 协议介绍,StreamJsonRpc 是一个 ...

  2. Otter(阿里开源项目Otter介绍)

    1.Otter-入门篇1(阿里开源项目Otter介绍) https://my.oschina.net/wenzhenxi/blog/719095 2.Otter-入门篇2(Manager安装配置) h ...

  3. 工业通信的开源项目 HslCommunication 介绍

    前言: 本项目的孵化说来也是机缘巧合的事,本人于13年杭州某大学毕业后去了一家大型的国企工作,慢慢的走上了工业软件,上位机软件开发的道路.于14年正式开发基于windows的软件,当时可选的技术栈就是 ...

  4. .NET 开源项目 Anet 介绍

    使用 Anet 有一段时间了,已经在我的个人网站(如 bookist.cc)投入使用,目前没有发现什么大问题,所以才敢写篇文章向大家介绍. GitHub 地址: https://github.com/ ...

  5. [转].NET 开源项目 Anet 介绍

    使用 Anet 有一段时间了,已经在我的个人网站(如 bookist.cc)投入使用,目前没有发现什么大问题,所以才敢写篇文章向大家介绍. GitHub 地址: https://github.com/ ...

  6. 各类值得收藏的开源项目推荐介绍

    一.背景 对于测开同学来讲,现在想要开发一个项目,很多时候都不需要自己从零开始重复造轮子.目前市面上已经很多大佬们开源了一些非常不错的项目可以供大家学习借鉴使用,因此本篇文章为大家介绍搜集到的一些不错 ...

  7. .NET 开源项目 StreamJsonRpc 介绍[上篇]

    StreamJsonRpc 是一个实现了 JSON-RPC 通信协议的开源 .NET 库,在介绍 StreamJsonRpc 之前,我们先来了解一下 JSON-RPC. JSON-RPC 介绍 JSO ...

  8. 像用Oracle一样用openGauss - 云和恩墨开源项目compat-tools介绍

    点击上方"蓝字" 关注我们,享更多干货! 近年来,随着国产数据库势如破竹般地快速发展,作为开源世界新生力量的openGauss亦得到了市场的青睐,尤其在云和恩墨推出的商业发行版Mo ...

  9. .NET 开源项目 StreamJsonRpc 介绍[中篇]

    阅读本文大概需要 11 分钟. 上一篇介绍了一些预备知识,包括 JSON-RPC 介绍和实现了 JSON-RPC 的 StreamJsonRpc 介绍,讲到了 StreamJsonRpc 可以通过 . ...

最新文章

  1. java csv格式文件写入_java csv文件写入
  2. vue 判断是否位 float_VUE中条件注释法css,判断ie浏览器
  3. python画动态爱心-使用Python画出小人发射爱心的代码
  4. SpringBoot笔记:SpringBoot2.3集成Logback日志组件配置
  5. Vue 模块化开发(构建项目常用工具)
  6. 如何循环数据库中的所有表名?
  7. 论一只爬虫的自我修养11:Scrapy框架之初窥门径
  8. windows上查看MD5
  9. SmartSVN忽略文件与文件夹的设置
  10. Android图片颜色混合算法
  11. 微积分(四)——多元函数微分总结
  12. HTML 管理员登陆小功能 连接数据库
  13. GPU卡的主流调度平台
  14. git merge冲突解决
  15. Asp.Net 密码加密技术
  16. 中国大学慕课第六周编程题
  17. VS2022 与 C语言:初学者
  18. html5扩展函数的使用方法,知识分享:JavaScript基础语法
  19. 视频 | 你不知道的开源60年秘史
  20. Cache与内存二三事

热门文章

  1. 欢迎与我一起交流安全管理平台
  2. 大端(Big Endian)、小端(Little Endian)
  3. .NET 6 攻略大全(一)
  4. redis缓存设计要点随谈
  5. 记一次 .NET 某市附属医院 Web程序 偶发性CPU爆高分析
  6. 如何高效的比较两个 Object 对象是否相等?
  7. 【全】.net core平台单元/集成测试结果、覆盖率、圈复杂度到可视化HTML报告之路...
  8. WPF实现时间轴(仿Gitee)
  9. 如何在.NET Core中为gRPC服务设计消息文件(Proto)
  10. Azure data studio 跨平台数据库管理工具试用