Polly简介 — 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. 弹性策略的更多相关文章
- Polly简介 — 3. 执行策略
执行策略 执行策略的常见方式是调用策略的Execute函数 var policy = Policy.Handle<TimeoutException>().Retry();policy.Ex ...
- Polly简介 — 1. 故障处理策略
Polly 是 .Net 下的一套瞬时故障处理及恢复的函式库,可让开发者以fluent及线程安全的方式来应用诸如Retry.Circuit Breaker.Timeout.Bulkhead Isola ...
- Linux防火墙简介 – iptables配置策略
Linux防火墙简介 – iptables配置策略 Netfilter/iptables简介 要想真正掌握Linux防火墙体系,首先要搞清楚Netfilter和iptables的关系,Netfilte ...
- 基于.NET的弹性及瞬间错误处理库Polly
本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET的弹性及瞬间错误处理库, 它允许开发人员以顺畅及 ...
- .NET的弹性及瞬间错误处理库Polly
原文:.NET的弹性及瞬间错误处理库Polly 本文基本是官方说明的翻译和总结(https://github.com/App-vNext/Polly) 什么是Polly? Polly是一款基于.NET ...
- 在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务
在 ASP.NET Core Web API中使用 Polly 构建弹性容错的微服务 https://procodeguide.com/programming/polly-in-aspnet-core ...
- NET Core微服务之路:弹性和瞬态故障处理库Polly的介绍
前言 上一节中我们介绍了Ocelot的常见使用配置,通过json配置文件,实现API网关的请求处理.和一个使用DownStream扩展下游中间件,来实现Http转RPC的简单实现,功能不算强大,但可以 ...
- .NET Core 微服务之Polly熔断策略
紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间内熔断该服务的调用,熔断期间的请求将不再继续调 ...
- 微服务之Polly熔断策略
NET Core 微服务之Polly熔断策略 紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间 ...
随机推荐
- 缓存数据库-redis(订阅发布)
一:Redis 发布订阅 Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息. Redis 客户端可以订阅任意数量的频道. 下图展示了频道 c ...
- 洛谷P2018消息传递
传送门啦 这个树形dp就没那么简单了,运用了一下贪心的思想 不同的排序方法对应着不同的转移方程,如果我们用 $ f[x] = max(f[x] , b[i] +cnt - i + 1) $ 来进行转移 ...
- MySQL学习笔记:regexp正则表达式
在MySQL中,模糊搜索的时候主要用两种方式: 1.like2.regexp + 正则表达式 性能优于like 正则表达式描述了一组字符串. 最简单的正则表达式是不含任何特殊字符的正则表达式.例如,正 ...
- MySQL 存储过程入门
存储过程是带有逻辑的SQL语句,优点是执行效率高.缺点是可移植性差 1.存储过程语法 DELIMITER $ --声明结束符 CREATE PROCEDURE pro_test() --创建存储过程 ...
- java对象与xml相互转换工具类
public class XmlHelper { /** * Object转XML * * @param object * @return * @throws Exception */ public ...
- MyBatis的动态插入语句(经常报‘无效的列类型’)
最近在工作中经常遇到一个情况:通过mybatis的标签执行插入语句,当表中字段比较多的时候,需要全部插入,而有时候的需求是只插入其中几个字段,但是会报错. 原来的语句,必须把所有字段都Set值. &l ...
- Oracle常用sql语句。
最近工作中遇到了一些与oracle相关的问题,稍微整理一些工作中用到的SQL语句 时间相关 --查询距当前时间十分钟内的数据 select sysdate -interval '10' minute ...
- Ninject中调用webapi卡住的情况解决
过年这两天在家做项目,把mvc升级到了5.1,webapi升级到了2.1,忽然发现一个问题,在某些页面上ajax调用webapi时会发现卡死现象,CPU也没有被占用,就是网页一些在加载也不报错,经过2 ...
- 《精通Python设计模式》学习结构型之代理模式
这种模式,总会让人想到SRPING中的AOP, 不同语言有不同的实现方式吧. class SensitiveInfo: def __init__(self): self.users = ['nick' ...
- OpenCV持久化(一)
在OpenCV中,采用FileStorage类进行数据持久化,可以采用XML或YAML格式存储数据. 将数据写入XML或YAML文件,可采用以下步骤: 1.创建FileStorage对象.可以调用构造 ...