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

  1. 定义策略
  2. 应用策略

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 Isolation)

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

个任务并发执行
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简介 — 2. 弹性策略的更多相关文章

  1. Polly简介 — 3. 执行策略

    执行策略 执行策略的常见方式是调用策略的Execute函数 var policy = Policy.Handle<TimeoutException>().Retry();policy.Ex ...

  2. Polly简介 — 1. 故障处理策略

    Polly 是 .Net 下的一套瞬时故障处理及恢复的函式库,可让开发者以fluent及线程安全的方式来应用诸如Retry.Circuit Breaker.Timeout.Bulkhead Isola ...

  3. Linux防火墙简介 – iptables配置策略

    Linux防火墙简介 – iptables配置策略 Netfilter/iptables简介 要想真正掌握Linux防火墙体系,首先要搞清楚Netfilter和iptables的关系,Netfilte ...

  4. 基于.NET的弹性及瞬间错误处理库Polly

    本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及 ...

  5. .NET的弹性及瞬间错误处理库Polly

    原文:.NET的弹性及瞬间错误处理库Polly 本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET ...

  6. 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务

    在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...

  7. NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍

    前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...

  8. .NET Core 微服务之Polly熔断策略

    紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间内熔断该服务的调用,熔断期间的请求将不再继续调 ...

  9. 微服务之Polly熔断策略

    NET Core 微服务之Polly熔断策略 紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间 ...

随机推荐

  1. 如何成为技术大牛——阿里CodeLife

    天天写业务代码的程序员,怎么成为技术大牛,开始写技术代码? 几个误区 跟着大牛,就可以成为大牛.首先,大牛时间很宝贵,不可能花很多时间去指导你:其次,简单的模仿大牛,只能学到表面知识,不可能成为大牛: ...

  2. python面向对象(二)之封装

    封装定义: 在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用. 即"封装"就是将抽象得到的数 ...

  3. 签名DLL

    签名DLL 首先需要一个密钥文件,后缀为.snk 密钥文件使用sn.exe 创建: sn.exe /k MySingInKey.snk  sn.exe 工具的具体使用,可以通过 sn.exe /h 或 ...

  4. java基础36 双例集合Map下的HashMap和TreeMap集合

    单例集合体系: ---------| collection  单例集合的根接口--------------| List  如果实现了list接口的集合类,具备的特点:有序,可重复       注:集合 ...

  5. P1183 多边形的面积

    一道睡论数论题 其实是AC300祭才做的水题 题意: 很直白的的题意啊,就是求任意一个多边形的面积 所以我们来安利一下一个求多边形面积的数学通式: 给定多边形的顶点坐标(有序),让你来求这个多边形的面 ...

  6. 20165203《Java程序设计》第五周学习总结

    教材学习内容总结 第七章 内部类 注意内部类和外嵌类的关系: 外嵌类的成员变量和方法在内部类有效 内部类的类体不可以声明static变量和方法.外嵌类的类体可以用内部类声明对象. 内部类仅供它的外嵌类 ...

  7. 第一篇CodeIgniter框架的下载及安装

    初次学习Php,网上搜了很多php框架,最后选择了CodeIgniter. 安装环境:php5+mysql6.5+iis7 我的电脑是用来办公写文档用的,win7系统,不想换系统,所以就安装了win7 ...

  8. asp.net 微信公众号源码

    需要源码,请加QQ:858-048-581 功能菜单 该源码功能十分的全面,具体介绍如下:1.菜单回复:微信自定义回复.关注时回复.默认回复.文本回复.图文回复.语音回复. 请求回复记录.LBS位置回 ...

  9. HTML/CSS权值继承

    <style type="text/css">p{color:red;}.first{color:green;}/*因为权值高显示为绿色*/ span{color:pi ...

  10. 转发:RocketMQ与kafka的对比

    淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用Mysql作为消息存储媒介,可完全水平扩容,为了进一步降低成本,我们认为存储部分可以进一步优化,2011年初,Linkin开源了Kaf ...