您的位置:首页 > 教程 > ASP.NET > .Net弹性和瞬态故障处理库Polly实现弹性策略

.Net弹性和瞬态故障处理库Polly实现弹性策略

2022-06-29 18:00:57 来源:易采站长站 作者:

.Net弹性和瞬态故障处理库Polly实现弹性策略

和故障处理策略不同的是,弹性策略并不是针对委托执行过程中的异常进行处理,而是改变委托本身的行为,因此弹性策略并没有故障定义这一过程,它的处理流程为:

    定义策略应用策略

    Polly对弹性策略也做了不少支持,本文这里就简单的介绍一下。

    弹性策略:超时(Timeout)

    超时策略用于控制委托的运行时间,如果达到指定时间还没有运行,则触发超时异常。

    Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Pessimistic);

    超时策略常见的重载版本有如下几个:

    Policy.Timeout(300);
    Policy.Timeout(TimeSpan.FromMilliseconds(3));
    Policy.Timeout(() => TimeSpan.FromSeconds(3));
    Policy.Timeout(TimeSpan.FromSeconds(3), TimeoutStrategy.Optimistic);

    超时策略:

    Polly支持两种超时策略:

      TimeoutStrategy.Pessimistic:>当委托到达指定时间没有返回时,不继续等待委托完成,并抛超时TimeoutRejectedException异常。TimeoutStrategy.Optimistic:乐观模式
      这个模式依赖于 co-operative cancellation,只是触发CancellationTokenSource.Cancel函数,需要等待委托自行终止操作。

      其中悲观模式比较容易使用,因为它不需要在委托额外的操作,但由于它本身无法控制委托的运行,函数本身并不知道自己被外围策略取消了,也无法在超时的时候中断后续行为。因此用起来反而还不是那么实用。

      一个乐观模式的的策略示例如下:

      var policy = Policy.Timeout(300); 
      var cts = new CancellationTokenSource();
      policy.Execute(ct =>
      {
          for (int i = 0; i < 1000; i++)
          {
              Thread.Sleep(100);
              ct.ThrowIfCancellationRequested();
          }
      }, cts.Token);

      复合策略:

      在日常的使用中,仅仅只有超时往往是并不够的,很多时候还需要和重试等其它故障处理策略一起使用,如:

      Policy.Handle<TimeoutRejectedException>()
          .Retry(3)
          .Wrap(Policy.Timeout(3, TimeoutStrategy.Pessimistic));

      弹性策略:无操作(NoOp)

      在开发过程中,处于测试或定位问题时的需要,有时我们也需要一个没有任何行为的策略,Polly系统默认提供了一个.

      Policy.NoOp();

      这个啥都没干,也没啥好介绍的了。

      弹性策略:缓存(Cache)

      有的时候,数据更新并不是频繁的,此时可以使用缓存策略减少对服务的访问,提高系统性能:

      var memoryCacheProvider =
          new Polly.Caching.MemoryCache.MemoryCacheProvider(new System.Runtime.Caching.MemoryCache("cache"));
      
      var cachePolicy = Policy.Cache(memoryCacheProvider, TimeSpan.FromMinutes(5));
      
      //Context.ExecutionKey就是cache的key
      var context = new Context("cache_key");
      for (int i = 0; i < 3; i++)
      {
          var cache = cachePolicy.Execute(_ =>
          {
              Console.WriteLine("get value");
              return 3;
          }, context);
          Console.WriteLine(cache);
      }

      PS:这个示例使用了MemoryCache,需要使用Nuget安装Polly.Caching.MemoryCache程序包,以及添加System.Runtime.Caching的引用。

      从运行结果可以看到,虽然三次执行都有结果,但系统只有第一次才需要执行函数,剩下两次都是直接从缓存中获取的结果。

      系统也提供了多种不同的过期策略:

      Policy.Cache(memoryCacheProvider, new AbsoluteTtl(DateTimeOffset.Now.Date.AddDays(1)));
      Policy.Cache(memoryCacheProvider, new SlidingTtl(TimeSpan.FromMinutes(5)));

      对于布式缓存,Polly也有默认的实现,只需要安装Polly.Caching.IdistributedCache程序包即可,它提供了SqlServer和Redis的支持。

      关于Cache的更多内容,可以参考官方文档:Cache

      弹性策略:舱壁隔离(Bulkhead>

      舱壁隔离是一种并发控制的行为,并发控制是一个比较常见的模式,Polly也提供了这方面的支持,如:

      //该策略下最多只有12个任务并发执行
      Policy.Bulkhead(12);

      超过了并发数的任务会抛BulkheadRejectedException,如果要放在队列中等待,Polly也提供了等待队列的支持:

      Policy.Bulkhead(12, 100);

      这种方式下,有12个并发任务,每个任务维持着一个并发队列,每个队列可以自持最大100个任务。

      不过,和微软自己的DataFlow模块比起来,感觉Polly模块的并发控制的功能还是比较弱的。不过这也它本身的应用场景也相关,如果需要更强大的策略,也可以自行封装。

      弹性策略:策略封装(PolicyWrap)

      我们可以通过PolicyWrap的方式,封装出一个更加强大的策略:

      var fallback = Policy<int>.Handle<TimeoutException>().Fallback(100);
      var retry = Policy<int>.Handle<TimeoutException>().Retry(2);
      
      Policy.Wrap(fallback, retry);

      这个策略就是将Retry和Fallback组合起来,形成一个retry and fallback的策略,也可以写成如下形式:

      var retryAndFallback = fallback.Wrap(retry);

      当执行这个新策略时:

      retryAndFallback.Execute(DoSomething);

      等价于执行:

      fallback.Execute(()=> retry.Execute(DoSomething));

      到此这篇关于Polly实现弹性策略的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持易采站长站。

      如有侵权,请联系QQ:279390809 电话:15144810328

相关文章

  • [Asp.Net Core] 浅谈Blazor Server Side

    [Asp.Net Core] 浅谈Blazor Server Side

    在2016年, 本人就开始了一个内部项目, 其特点就是用C#构建DOM树, 然后把DOM同步到浏览器中显示. 并且在一些小工程中使用. 3年下来, 效果很不错, 但因为是使用C#来构建控件树, 在没有特定
    2020-07-01
  • asp.net生成Excel并导出下载五种实现方法

    asp.net生成Excel并导出下载五种实现方法

    方法一 通过GridView(简评:方法比较简单,但是只适合生成格式简单的Excel,且无法保留VBA代码),页面无刷新 aspx.cs部分 代码如下: using System; using System.Collections; using System.Configuration; usi
    2019-05-16
  • Asp.Net Core用NLog记录日志操作方法

    Asp.Net Core用NLog记录日志操作方法

    需求 1.日志自动写入到数据库、写入到文件 2.appsettings.json数据库连接更改后,不需要去改NLog中的连接地址,启动网站或项目时自动检测变动然后去更改,以appsettings.json为准,保持同步
    2019-11-19
  • 使用vs2019加.net core 对WeiApi的创建过程详解

    使用vs2019加.net core 对WeiApi的创建过程详解

    vs2019创建webapi 1.创建新的项目 2.选择.NET CORE的ASP .NET CORE WEB应用程序 3.定义项目名称和存放地点 4.选择API创建项目 5.删除原本的无用的类 6.添加新的方法类 7.设置路由 using Microsoft.AspNe
    2020-07-03
  • 教你Asp.net下使用mysql数据库的步骤

    教你Asp.net下使用mysql数据库的步骤

    1. 首先需要安装mysql, 易采站长站下载地址: //www.jb51.net/softs/2193.html 或者去mysql.com官网都可以,一路next,安装好后,有个简单配置,提示有个设置登录密码和服务名称, 默认localhost,用
    2019-05-16
  • [Asp.Net Core]用Blazor Server Side实现图片验证码

    [Asp.Net Core]用Blazor Server Side实现图片验证码

    关于Blazor 由于在国内, Blazor一点都不普及, 在阅读此文前, 建议读者先翻看我之前写的随笔, 了解Blazor Server Side的特点. 在一段时间内, 我会写一些解说分析型的 "为什么选择 Blazor Server
    2020-07-01
  • 详解ASP.NET Razor 语法

    详解ASP.NET Razor 语法

    Razor 同时支持 C# (C sharp) 和 VB (Visual Basic)。 主要的 Razor C# 语法规则 Razor 代码块包含在 @{ ... } 中 内联表达式(变量和函数)以 @ 开头 代码语句用分号结束 变量使用 var 关键字声明 字符
    2020-07-07
  • .Net Core中使用ExceptionFilter过滤器的方法

    .Net Core中使用ExceptionFilter过滤器的方法

    .Net Core中有各种Filter,分别是AuthorizationFilter、ResourceFilter、ExceptionFilter、ActionFilter、ResultFilter。可以把他们看作是.Net Core自带的AOP的扩展封装。 今天来看其中的一种:ExceptionFilter(用于
    2020-03-03