(5)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 熔断降级(Polly)
一、 什么是熔断降级
熔断就是“保险丝”。当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成“雪崩”,或者大量的超时等待导致系统卡死。
降级的目的是当某个服务提供者发生故障的时候,向调用方返回一个错误响应或者替代响应。举例子:调用联通接口服务器发送短信失败之后,改用移动短信服务器发送,如果移动短信服务器也失败,则改用电信短信服务器,如果还失败,则返回“失败”响应;在从推荐商品服务器加载数据的时候,如果失败,则改用从缓存中加载,如果缓存中也加载失败,则返回一些本地替代数据。
二、 Polly 简介
.Net Core 中有一个被.Net 基金会认可的库 Polly,可以用来简化熔断降级的处理。主要功能:重试(Retry);断路器(Circuit-breaker);超时检测(Timeout);缓存(Cache);降级(FallBack);
官网:https://github.com/App-vNext/Polly
介绍文章:https://www.cnblogs.com/CreateMyself/p/7589397.html
Nuget安装指令:Install-Package Polly -Version 6.0.1
Polly 的策略由“故障”和“动作”两部分组成,“故障”包括异常、超时、返回值错误等情况,“动作”包括 降级(FallBack)、重试(Retry)、熔断(Circuit-breaker)等。
策略用来执行可能会有有故障的业务代码,当业务代码出现“故障”中情况的时候就执行“动作”。
由于实际业务代码中故障情况很难重现出来,所以 Polly 这一些都是用一些无意义的代码模拟出来。
Polly 也支持请求缓存“数据不变化则不重复自行代码”,但是和新版本兼容不好,而且功能局限性很大,因此这里不讲。
由于调试器存在,看不清楚 Polly 的执行过程,因此本节都用【开始执行(不调试)】
三、Polly简单使用
使用Policy的静态方法创建ISyncPolicy实现类对象,创建方法既有同步方法也有异步方法,根据自己的需要选择。下面先演示同步的,异步的用法类似。
举例:当发生ArgumentException异常的时候,执行Fallback代码。
Policy policy = Policy .Handle<ArgumentException>() //故障 .Fallback(() =>//动作 { Console.WriteLine("执行出错"); }); policy.Execute(() => {//在策略中执行业务代码 //这里是可能会产生问题的业务系统代码 Console.WriteLine("开始任务"); throw new ArgumentException("Hello world!"); Console.WriteLine("完成任务"); }); Console.ReadKey();
如果没有被Handle处理的异常,则会导致未处理异常被抛出。
还可以用Fallback的其他重载获取异常信息:
Policy policy = Policy .Handle<ArgumentException>() //故障 .Fallback(() =>//动作 { Console.WriteLine("执行出错"); },ex=> { Console.WriteLine(ex); }); policy.Execute(() => { //在策略中执行业务代码 //这里是可能会产生问题的业务系统代码 Console.WriteLine("开始任务1"); throw new ArgumentException("Hello1 world!"); Console.WriteLine("完成任务"); });
如果Execute中的代码是带返回值的,那么只要使用带泛型的Policy<T>类即可:
Policy<string> policy = Policy<string> .Handle<Exception>() //故障 .Fallback(() =>//动作 { Console.WriteLine("执行出错"); return "降级的值"; }); string value = policy.Execute(() => { Console.WriteLine("开始任务"); throw new Exception("Hello world!"); Console.WriteLine("完成任务"); return "正常的值"; }); Console.WriteLine("返回值:"+value);
FallBack的重载方法也非常多,有的异常可以直接提供降级后的值。
(*)异常中还可以通过lambda表达式对异常判断“满足***条件的异常我才处理”,简单看看试试重载即可。还可以多个Or处理各种不同的异常。
(*)还可以用HandleResult等判断返回值进行故障判断等,我感觉没太大必要。
四、重试处理
Policy policy = Policy .Handle<Exception>() .RetryForever(); policy.Execute(() => { Console.WriteLine("开始任务"); != ) { throw new Exception("出错"); } Console.WriteLine("完成任务"); });
RetryForever()是一直重试直到成功
Retry()是重试最多一次;
Retry(n) 是重试最多n次;
WaitAndRetry()可以实现“如果出错等待100ms再试还不行再等150ms秒。。。。”,重载方法很多,不再一一介绍。还有WaitAndRetryForever。
五、 短路保护 Circuit Breaker
出现N次连续错误,则把“熔断器”(保险丝)熔断,等待一段时间,等待这段时间内如果再Execute 则直接抛出BrokenCircuitException异常,根本不会再去尝试调用业务代码。等待时间过去之后,再执行Execute的时候如果又错了(一次就够了),那么继续熔断一段时间,否则就恢复正常。
这样就避免一个服务已经不可用了,还是使劲的请求给系统造成更大压力。
Policy policy = Policy .Handle<Exception>() .CircuitBreaker(,TimeSpan.FromSeconds());//连续出错6次之后熔断5秒(不会再去尝试执行业务代码)。 while(true) { Console.WriteLine("开始Execute"); try { policy.Execute(() => { Console.WriteLine("开始任务"); throw new Exception("出错"); Console.WriteLine("完成任务"); }); } catch(Exception ex) { Console.WriteLine("execute出错"+ex); } Thread.Sleep(); }
其计数的范围是policy对象,所以如果想整个服务器全局对于一段代码做短路保护,则需要共用一个policy对象。
六、策略封装,包裹Warp
可以把多个ISyncPolicy合并到一起执行:
policy3= policy1.Wrap(policy2);
执行policy3就会把policy1、policy2封装到一起执行。
Policy的静态方法Wrap可以把更多的policy一起封装:
policy9=Policy.Wrap(policy1, policy2, policy3, policy4, policy5);
七、超时处理
这些处理不能简单的链式调用,要用到Wrap。例如下面实现“出现异常则重试三次,如果还出错就FallBack”这样是不行的
Policy policy = Policy.Handle<Exception>().Retry(3).Fallback(()=> { Console.WriteLine("执行出错"); });//这样不行,系统会直接报错
注意Wrap是有包裹顺序的,内层的故障如果没有被处理则会抛出到外层。
下面代码实现了“出现异常则重试三次,如果还出错就FallBack”
Policy policyRetry = Policy.Handle<Exception>().Retry(); //出现异常重试三次 Policy policyFallback = Policy .Handle<Exception>() .Fallback(()=> { Console.WriteLine("降级"); }); //Wrap:包裹。policyRetry在里面,policyFallback裹在外面。 //如果里面出现了故障,则把故障抛出来给外面 Policy policy = policyFallback.Wrap(policyRetry); policy.Execute(()=> { Console.WriteLine("开始任务"); != ) { throw new Exception("出错"); } Console.WriteLine("完成任务"); });
运行结果:
Timeout是定义超时故障,如果超时会抛出TimeoutRejectedException异常。
Policy policy = Policy.Timeout(, TimeoutStrategy.Pessimistic);// 创建一个3秒钟(注意单位)的超时策略。
Timeout生成的Policy要和其他Policy一起Wrap使用。
超时策略一般不能直接用,而是和其他封装到一起用:
Policy policy = Policy .Handle<TimeoutRejectedException>() //定义所处理的故障 .Fallback(() => { Console.WriteLine("降级"); }); policy = policy.Wrap(Policy.Timeout(,TimeoutStrategy.Pessimistic)); policy.Execute(()=> { Console.WriteLine("开始任务"); Thread.Sleep(); Console.WriteLine("完成任务"); });
执行结果:
上面的代码就是如果执行超过2秒钟,则直接Fallback。 这个的用途:请求网络接口,避免接口长期没有响应造成系统卡死。
八、Polly 的异步用法
所有方法都用Async方法即可,Handle由于只是定义异常,所以不需要异常方法:
带返回值的例子:
Policy<byte[]> policy = Policy<byte[]> .Handle<Exception>() .FallbackAsync(async c => { Console.WriteLine("降级"); ]; },async r=> { Console.WriteLine(r.Exception); }); policy = policy.WrapAsync( Policy.TimeoutAsync(, TimeoutStrategy.Pessimistic, async(context, timespan, task) => { Console.WriteLine("timeout"); })); var bytes = await policy.ExecuteAsync(async () => { Console.WriteLine("开始任务"); HttpClient httpClient = new HttpClient(); var result = await httpClient.GetByteArrayAsync("http://static.rupeng.com/upload/chatimage/20183/07EB793A4C247A654B31B4D14EC64BCA.png"); Console.WriteLine("完成任务"); return result; }); Console.WriteLine("bytes长度"+bytes.Length);
执行结果:
没返回值的例子:
Policy policy = Policy .Handle<Exception>() .FallbackAsync(async c => { Console.WriteLine("降级"); },async ex=> {//对于没有返回值的,这个参数直接是异常 Console.WriteLine(ex); }); policy = policy.WrapAsync(Policy.TimeoutAsync(, TimeoutStrategy.Pessimistic, async(context, timespan, task) => { Console.WriteLine("timeout"); })); await policy.ExecuteAsync(async () => { Console.WriteLine("开始任务"); );//注意不能用Thread.Sleep(5000); Console.WriteLine("完成任务"); });
执行结果:
注:此文章是我看杨中科老师的.Net Core微服务第二版和.Net Core微服务第二版课件整理出来的
(5)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 熔断降级(Polly)的更多相关文章
- 【新书推荐】《ASP.NET Core微服务实战:在云环境中开发、测试和部署跨平台服务》 带你走近微服务开发
<ASP.NET Core 微服务实战>译者序:https://blog.jijiechen.com/post/aspnetcore-microservices-preface-by-tr ...
- ASP.NET Core 微服务初探[1]:服务发现之Consul
ASP.NET Core 微服务初探[1]:服务发现之Consul 在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件 ...
- (8)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot网关(Api GateWay)
说到现在现有微服务的几点不足: 1) 对于在微服务体系中.和 Consul 通讯的微服务来讲,使用服务名即可访问.但是对于手 机.web 端等外部访问者仍然需要和 N 多服务器交互,需要记忆他们的服务 ...
- (7)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 利用Polly+AOP+依赖注入封装的降级框架
创建简单的熔断降级框架 要达到的目标是: 参与降级的方法参数要一样,当HelloAsync执行出错的时候执行HelloFallBackAsync方法. public class Person { [H ...
- (1)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 什么是微服务架构,.netCore微服务选型
开发工具:VS2017 .Net Core 2.1 什么是微服务?单体结构: 缺点: 1)只能采用同一种技术,很难用不同的语言或者语言不同版本开发不同模块: 2)系统耦合性强,一旦其中一个模块有问题, ...
- (11)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Thrift高效通讯 (完结)
一. 什么是 RPC Restful 采用 Http 进行通讯,优点是开放.标准.简单.兼容性升级容易: 缺点是性能略低.在 QPS 高或者对响应时间要求苛刻的服务上,可以用 RPC(Remote P ...
- (10)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot+Identity Server
用 JWT 机制实现验证的原理如下图: 认证服务器负责颁发 Token(相当于 JWT 值)和校验 Token 的合法性. 一. 相关概念 API 资源(API Resource):微博服务器接口. ...
- (6)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- AOP框架
AOP 框架基础 要求懂的知识:AOP.Filter.反射(Attribute). 如果直接使用 Polly,那么就会造成业务代码中混杂大量的业务无关代码.我们使用 AOP (如果不了解 AOP,请自 ...
- ASP.NET Core微服务+Tabler前端框架搭建个人博客1--开始前想说的话
写在前面 本人为在读研究生,特别喜欢.NET,觉得.NET的编程方式.语法都特别友好,学习.NET Core已经差不多有一年半了,从一开始不知道如何入门到现在终于可以编写一些小的应用程序,想一想还是非 ...
随机推荐
- Markdown:常用语法
1.标题 说明:一共可以6级标题,几级几个# 一级标题 #一级标题 2.代码 用前后扩上 Hello World! 3.代码块 用前后扩上 Hello World! 4.加粗 加粗了 **加粗了** ...
- Maven和Solr简单总结
一.1.Maven介绍 Maven是一个项目管理工具,Maven通过POM项目对象模型,对象项目进行管理,通过一个配置文件(xml文件)进行项目的管理.对象项目的声明周期中每个阶段进行管理(清理,编译 ...
- 前端 CSS预处理器Less
引文 Less是一种动态的样式语言.Less扩展了CSS的动态行为,比如说,设置变量(Variables).混合书写模式(Mixins).操作(Operations)和功能(Functions)等等, ...
- python之restful api(flask)获取数据
需要用到谷歌浏览器的扩展程序 Advanced Rest Client进行模拟请求 1.直接上代码 from flask import Flask from flask import request ...
- 使用Visual Studio Team Services敏捷规划和项目组合管理(五)——组合管理
使用Visual Studio Team Services敏捷规划和项目组合管理(五)--组合管理 组合待办事项为产品所有者提供关于几个敏捷特性团队工作的洞察.产品所有者可以将高优先级的目标定义为Ep ...
- Jmeter学习——http请求Content encoding的重要性
今天在测试一个接口的时候,遇到的问题,困扰了我一天 下面是一个接口,使用的是post请求,Content-Type为application/json 返回参数如下: 瞬间懵逼了!!!为什么呢?渠道是存 ...
- MySQL查询日志总结
MySQL查询日志介绍 MySQL的查询日志记录了所有MySQL数据库请求的信息.无论这些请求是否得到了正确的执行.默认文件名为hostname.log.默认情况下MySQL查询日志是关闭的.生产环境 ...
- [20181007]12cR2 Using SQL Patch.txt
[20181007]12cR2 Using SQL Patch.txt --//12cR2 已经把sql打补丁集成进入dbms_sqldiag,不是11g的 DBMS_SQLDIAG_INTERNAL ...
- [20180810]exadata--豆腐渣系统的保护神.txt
[20180810]exadata--豆腐渣系统的保护神.txt --//最近一段时间,一直在看exdata方面的书籍,我个人的感觉exadata并非善长oltp系统,能通过OLTP获得好处的就算ex ...
- mssql-sqlserver入门必备知识收集
一.了解SQL 数据库的应用场景 sql 简介 二. 检索数据 SELECT语句 检索单个.多及所有列的方法分享 检索不同的值 限制结果 sqlserver注释编写方法 三.排序检索数据 ...