熔断降级是一个非常重要的概念,我们先说一下什么是熔断降级,咱们都知道服务发现,一个有问题的服务器没来得急注销过一会就崩溃掉了,那么我们的请求就有可能访问一个已经崩溃的服务器,那么就会请求失败,因为已经game over了。那么这个问题怎么解决呢,你一定要承认,这个问题是无法避免的。没有什么方法说,我拿到的服务器都没有问题,这事是不可能的,所以你要承认你会有机会拿到有问题的服务器。那么熔断降级就是来解决这种问题的。

一.什么是熔断

熔断就像是“保险丝”,当出现梦中状况时,切断服务,从而防止应用程序不断地尝试造成雪崩,这和我们农村的保险丝很像,天气热了防止火灾,那保险丝会自动断开,防止更大的损失。

降级的目的是当某个服务提供者发生故障的时候,向调用方返回一个错误响应替代响应。

比如我们要做一个双11活动的系统,那么比如一个抽奖的模块崩溃,这个时候呢广大客户端疯狂F5,就会导致整个集群雪崩,这个时候我们就应该中断。

还有一栗子,比如说电信和联通,它们在稳定,有也不稳定的时候,那么如果我们用它们的接口,如果电信崩了,我们就是用联通,这种操作的行为就叫做熔断降级。

其使用场景呢,例如,我们要展示商品信息,我们先从数据库读取,读取失败了,我们就通过cache/redis,如果再失败,我们通过固定的Javascript object 来绑定,如果再失败那就返回一个错误的信息。这就是完美的降低了错误。

这种错误的概率就犹如0.01*way³  就是1000次才会出现的概率。那如果是不熔断降级 就是100.以上一些栗子,好好读读即可。

二.Polly介绍

.Net Core 中有一个被.Net基金会认可的k库,可以用来进行熔断降级,主要功能:1.重试(retry);2.断路器(circuit-breaker);3.超时检测(timeout);4.缓存(cache);5.降级(fallback)

官方:https://github.com/app-vnext/polly  nuget: install-package Polly-Version 6.0.1

三.使用

创建项目与安装库,为了稳定还是选择6.0.1吧。

使用Policy的静态方法创建ISyncPolicy实现类对象,创建方法j既有同步方法也有异步方法,根据自己的需求来选择,下面先演示同步方法,异步的方法也类似。

static void Main(string[] args)
{
//handle 当发生argumentException的异常
Policy policy = Policy.Handle<ArgumentException>()
.Fallback(() =>
{
//就干什么事情
Console.WriteLine("出错了");
});
       //有可能异常的时候
policy.Execute(() =>
{
Console.WriteLine("开始执行");
throw new ArgumentException();
Console.WriteLine("执行结束");
});
}

我们运行一下,是如下结果。

但如果书我们故意写一个抛出异常,我们稍微修改一下代码。

policy.Execute(() =>
{
Console.WriteLine("开始执行");
throw new ArgumentException();
Console.WriteLine("执行结束");
});

上面呢,我么捕捉的是ArgumentException异常,那么我们如果是报的其他的错误应该会怎样呢?

policy.Execute(() =>
{
Console.WriteLine("开始执行");
throw new Exception();
Console.WriteLine("执行结束");
});

FallBack中有很多不同的重载,我们可以根据重载获取不同的报错信息,以下是所有的方法。

我们可以简单的去获取一个对象,代码如下:

 Policy policy = Policy.Handle<ArgumentException>()
.Fallback(() =>
{
//就干什么事情
Console.WriteLine("出错了");
},ex=> {
Console.WriteLine(ex.Message);
});
policy.Execute(() =>
{
Console.WriteLine("开始执行");
throw new ArgumentException();
Console.WriteLine("执行结束");
});

因为咱们的业务逻辑啊有可能是带返回值的,也有可能是不带返回值的。那如果你的业务逻辑是带返回值的,你就得用一个Policy带参的泛型来创建,那么这个Policy也是泛型的,在FallBack中也要 提一个替代值,因为毕竟是降级嘛,肯定要有一个值来进行替代。

Policy<string> policy = Policy<string>.Handle<Exception>()
.Fallback(() =>
{
return "降级后的值";
});
string value = policy.Execute(() => {
return "正常值";
});

四.重试处理

polly提供了重试处理机制,那么这个RetryForever()的场景不可能会出现,我也不知道它是处于什么个操作。我觉得这违背了熔断降级,这不可能让它重试的,那么以下就是用法,但是这根本用不着~

还是推荐使用Retry吧。Retry中可以写个int值进去,就是重试的次数,这个还是不错的!

Policy policy = Policy.Handle<Exception>().RetryForever();
policy.Execute(() => {
Console.WriteLine("play task!!");
if (DateTime.Now.Second % 10 != 0)
{
throw new Exception();
}
Console.WriteLine("完成任务!");
});

不过还是有比较正常点的方法,例如WaitAndRetry这个方法,等等再重试。这个很不错!这个方法里的重载非常之多。

Policy policy = Policy.Handle<Exception>().WaitAndRetry(100, i => TimeSpan.FromMinutes(100));
policy.Execute(() => {
Console.WriteLine("play task!!");
if (DateTime.Now.Second % 10 != 0)
{
throw new Exception();
}
Console.WriteLine("完成任务!");
});

五.短路保护Circuit Breaker

短路保护是什么意思呢,这个单词翻译过来就叫做线路切断器,出现N次连续错误,则把“熔断器”(保险丝)熔断,等待一段时间,等待这段时间内如果再Execute则直接抛出BrokenCircuitException异常,根本不会再去尝试调用业务代码。等待时间过去之后,再执行Execute的时候如果又错了(一次就够了),那么继续熔断一段时间,否则就恢复正常。这样就避免一个服务已经不可用了,还是使劲的请求给系统造成更大压力。

这样就避免了一个服务不可用了还在使劲的请求。

 Policy policy = Policy
.Handle<Exception>()
.CircuitBreaker(3, TimeSpan.FromSeconds(5));//连续出错3次之后熔断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(500);
}

这就像刚才我们说的,我设置了连续3次熔断,那么如果连续3次报错,那么直接不再执行以后的内容,这无疑是非常不错的机制。保证了服务器的性能丢失和不起眼的问题。

六.策略封装与超时处理

策略封装使用的方法是Policy提供的Wrap方法,英译叫做包裹,那么从单词的意思就知道,可以通过策略包裹策略来进行封装,即里面的不行,就走外面的。

Policy policyRetry = Policy.Handle<Exception>()
.Retry(3);
Policy policyFallback = Policy.Handle<Exception>()
.Fallback(() =>
{
Console.WriteLine("降级");
});
Policy policy = policyFallback.Wrap(policyRetry);
policy.Execute(() =>
{
Console.WriteLine("play task!!");
if (DateTime.Now.Second % 10 != 0)
{
throw new Exception();
}
Console.WriteLine("完成任务!");
});

注意这个wrap的包裹顺序的,外在后,内在前。再通过一个超时处理就可以对消耗时间够长的请求进行GG了。

那么你就可以通过超时处理来对我们文章开头的诉说进行一个非常生动形象的通过代码来宣誓。下面说明超时异常的说明

Policy policytimeout = Policy.Timeout(3, TimeoutStrategy.Pessimistic);
Policy policyFallBack = Policy.Handle<TimeoutRejectedException>()
.Fallback(() =>
{
Console.WriteLine("熔断降级");
});
Policy policy = policyFallBack.Wrap(policytimeout);
policy.Execute(() =>
{
Console.WriteLine("完成任务");
Thread.Sleep(5000);
Console.WriteLine("完成任务");
});
Console.ReadKey();

这玩腻的用途不过就是:请求网络接口,避免接口长期没有响应造成系统卡死。

七.Polly的异步

     Test1().Wait(); //调用

        static async Task Test1()
{ Policy<byte[]> policy = Policy<byte[]>
.Handle<Exception>()
.FallbackAsync(async c => {
Console.WriteLine("执行出错");
return new byte[0];
}, async r => {
Console.WriteLine(r.Exception);
});
policy = policy.WrapAsync(Policy.TimeoutAsync(20, 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("https://www.cnblogs.com/images/logo_small.gif");
Console.WriteLine("完成任务");
return result;
});
Console.WriteLine("bytes长度" + bytes.Length);
}

使用Polly的异步,那么所有的方法都必须是异步,除了Handle方法,因为handle就不需要异步,也没有返回值。通过异步呢,所有的重载方法都构造了一遍,还是可以继续用的。那么这段代码的意思是,通过异步的方式如果我通过httpclient获取某站点的图片的base值,如果在此期间我定义了一个policy,抓住一个异常,如果说两秒之内还没有反应我就超时。直接终止。测试的时候 你可以把值 改变下。

八.最后

相信你跟着我写到现在,已经感到这代码已经非常恶心了,代码中有非常多冗余的代码,近期会使用AspectCore这个AOP框架,听别人说这个库不错,这和Spring cloud的Hystrix差不多。就这样了,再见,喜欢点个推荐!

三分钟学会.NET微服务之Polly的更多相关文章

  1. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  2. 微服务之Polly熔断策略

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

  3. 三分钟学会@Autowired@Qualifier@Primary注解

    三分钟学会@Autowired@Qualifier@Primary注解 2018.10.08 20:24 154浏览 今天主要简单的跟大家介绍一下spring自动装配相关的@Autowired,@Qu ...

  4. 三分钟学会使用Derby数据库

    Derby数据库是一个纯用Java实现的内存数据库,属于Apache的一个开源项目.由于是用Java实现的,所以可以在任何平台上运行:另外一个特点是体积小,免安装,java1.6开始集成了derby数 ...

  5. [转]三分钟学会.NET Core Jwt 策略授权认证

    [转]三分钟学会.NET Core Jwt 策略授权认证 一.前言# 大家好我又回来了,前几天讲过一个关于Jwt的身份验证最简单的案例,但是功能还是不够强大,不适用于真正的项目,是的,在真正面对复杂而 ...

  6. 第三十九章 微服务CICD(1)- gitlab搭建与使用(docker版)

    一.下载docker镜像 前提:docker引擎已经安装好. docker pull gitlab/gitlab-ce gitlab是8.13.1版本. 二.启动应用 docker run -d -h ...

  7. .NET Core 微服务之Polly重试策略

    接着上一篇说,正好也是最近项目里用到了,正好拿过来整理一下,园子里也有一些文章介绍比我详细. 简单介绍一下绍轻量的故障处理库 Polly  Polly是一个.NET弹性和瞬态故障处理库 允许我们以非常 ...

  8. SpringCloud学习笔记(三):Rest微服务构建案例工程模块

    需要具备的知识 1 springmvc+mybatis+mysql 2 Consumer消费者(Client)通过REST调用Provider提供者(Server)提供的服务 3 Maven的分包分模 ...

  9. docker微服务部署之:三,搭建Zuul微服务项目

    docker微服务部署之:二.搭建文章微服务项目 一.新增demo_eureka模块,并编写代码 右键demo_parent->new->Module->Maven,选择Module ...

随机推荐

  1. Eclipse中Maven Install时发生错误

    问题描述 要把一个本地包保存进本地maven库中, 所以对该project执行了run as => Maven Install, 结果报下面的错误. 解决办法 1. 通过命令窗口手动创建这两个文 ...

  2. Java 读书笔记 (十五) Java 异常处理

    捕获异常 使用try 和catch关键字可以捕获异常.try/catch 代码块放在异常可能发生的地方. try/catch 代码块中的代码称为保护代码 ,使用try/catch的语法如下: try ...

  3. go语言nsq源码解读一-基本介绍

    简单介绍一下nsq. 参考 http://feilong.me/2013/05/nsq-realtime-message-processing-system 的介绍:NSQ是由知名短链接服务商bitl ...

  4. laravel 分页和共多少条 加参数的分页链接

    <div class="pagers "> <span class="fs pager">共 {{$trades->total() ...

  5. 实践 Network Policy - 每天5分钟玩转 Docker 容器技术(172)

    为了演示 Network Policy,我们先部署一个 httpd 应用,其配置文件 httpd.yaml 为: httpd 有三个副本,通过 NodePort 类型的 Service 对外提供服务. ...

  6. c语言最大公约数及最小公倍数的详解

    今天我打算把,学习到的一些知识整理一下,方便给以后的学弟学妹做一个参考! 这一次是关于最大公约数和最小公倍数的知识:这是百度关于最大公约数的介绍 感谢我的一位学姐的博文,让我能够更快的明白! 求最小公 ...

  7. MYSQL——解题查询语句答题思路,再难的查询都不怕!

    select查询语句,作为测试人员,使用此语句是家常便饭,是必须掌握的部分,由开始学习mysql到网上搜索试题做,开始做题一塌糊涂,拿到题目就晕,无从下手,现在慢慢总结了一套自己做题的方式,很开森,嘿 ...

  8. eShopOnContainers 知多少[9]:Ocelot gateways

    引言 客户端与微服务的通信问题永远是一个绕不开的问题,对于小型微服务应用,客户端与微服务可以使用直连的方式进行通信,但对于对于大型的微服务应用我们将不得不面对以下问题: 如何降低客户端到后台的请求数量 ...

  9. 一个比喻讲明Docker是什么

    之前一直听运维的同事讲Docker,说弄个Docker镜像,打包些应用什么的,还有时不时地在一些帖子里见到过关于Docker的三言两语,然后自己也自我感觉良好的把它总结归纳了一下认为:"往D ...

  10. 彻底理解浏览器的缓存机制(http缓存机制)

    一.概述 浏览器的缓存机制也就是我们说的HTTP缓存机制,其机制是根据HTTP报文的缓存标识进行的,所以在分析浏览器缓存机制之前,我们先使用图文简单介绍一下HTTP报文,HTTP报文分为两种: 同步s ...