Polly .NET open source project description

Today introduced a .NET open source library: Polly, it supports .NET Core, the current number Star in GitHub has exceeded 7,000, it is a powerful and useful .NET library.

Polly Introduction

The official introduction of Polly is this:

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.

Roughly translated meant: Polly .NET is a resilient and transient fault processing library that allows developers to Fluent and thread-safe way to achieve a retry, disconnect, time out, isolation and rollback strategies.

This description is a bit abstract, we work together to understand it.

First, that transient fault here contains an exception occurs and results of the program does not meet the expectations of developers appear. The so-called transient fault, that fault is not bound to happen, but occasionally may occur, such as the network occasionally unstable or suddenly can not access this failure. As for flexibility, refers to treatment strategies to deal with the failure of Polly diversity and flexibility of its various policy flexibility to define and combinations.

Let's show an example, we even more clear.

Troubleshooting Policy Example

An convention, create an empty Console project, and installation NuGet package:

Install-Package Polly

Basic usage policy Polly exception handling can be divided into three steps, comprising the step described in the following code:

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);
}

You can see from the example, Polly's API supports streaming (Fluent) call, easy to use. This very simple example of error handling policy, when a network error or exception request occurs, it retries three times. Figure we can see that during the execution of this strategy of operating results from the following:

Specifically, the following troubleshooting Polly support of various strategies.

Polly Seven Strategies

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 文档。

参考:

 

http://www.thepollyproject.org

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

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

 

原文链接:https://www.cnblogs.com/willick/p/polly.html

 

Guess you like

Origin www.cnblogs.com/88223100/p/polly.html