大佬教程收集整理的这篇文章主要介绍了再探Circuit Breaker之使用Polly,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
<h2 id="前言">前言
介绍了使用Steeltoe来处理服务熔断,这篇我们将用来处理服务熔断。
不废话了,直接进正题。
同样先定义一个简单的服务。
[Route("api/[controller]")] public class ValuesController : Controller { // GET api/values [httpGet] public String Get() { return "service--a"; } }
再来一个新服务去调用上面的服务。
定义一个用于访问服务的service接口和实现。
public interface IAservice { TaskGetAsync(); } public class Aservice : IAservice
{
private PolicyWrap_policyWrap; private ILogger _logger; public Aservice(ILoggerFactory loggerFactory) { _logger = loggerFactory.CreateLogger<Aservice>(); //超时 var timeout = Policy .TimeoutAsync(1,Polly.Timeout.TimeoutStrategy.Pessimistic,(context,ts,task) => { _logger.LogInformation("Aservice timeout"); return Task.CompletedTask; }); //熔断 var circuitBreaker = Policy .Handle<Exception>() .CircuitBreakerAsync(2,TimeSpan.FromSeconds(5),(ex,ts) => { _logger.LogInformation($"Aservice OnBreak -- ts = {ts.Seconds}s,ex.message = {ex.messagE}"); },() => { _logger.LogInformation("Aservice OnReset"); }); //fallBACk + 熔断 + 超时 _policyWrap = Policy<String> .Handle<Exception>() .fallBACkAsync(GetfallBACk(),(X) => { _logger.LogInformation($"Aservice fallBACk -- {x.Exception.messagE}"); return Task.CompletedTask; }) .WrapAsync(circuitBreaker) .WrapAsync(timeout); } //降级处理 private String GetfallBACk() { return "fallBACk"; } public async Task<String> GetAsync() { return await _policyWrap.ExecuteAsync(() => { return QueryAsync(); }); } private async Task<String> QueryAsync() { using (var client = new httpClient()) { var res = await client.GetStringAsync("http://localhost:9001/api/values"); return res; } }
}
要注意的有几个地方。
Polly没有既包含熔断又包含降级又包含超时的,这个需要自己去组合。相对来说,HyStrix在这一方面似乎好一点点。
但是,各有各的好,Polly分离了每一个模块,让我们自由组合,也是很灵活的。
所以可以看到,我们定义了3个Policy,再把它们Wrap起来。
另外,还在触发每一个Policy的时候,都会输出@R_450_11258@日记,方便我们后面看效果。
对于写日记这一块,个人认为对比Steeltoe,Polly的方式要更加方便和简单。
下面是控制器的使用。
// GET api/values [httpGet] public async TaskA([Fromservices]IAservice aservicE) { return await aservice.GetAsync(); }
还有一个关键的步骤:在Startup注册我们的Aservice。
services.AddSingleton();
切记是Singleton!不然熔断就不会起作用了!!
直接上效果图
title="再探Circuit Breaker之使用Polly" alt="再探Circuit Breaker之使用Polly" src="https://cn.js-code.com/res/2019/02-08/23/270458ee1e532d42696e81482d9f5b0d.gif">
简单说明一下这张图,一开始,服务A和调用方都是正常的,后面中断服务A,使其不可用,这个时候调用方就会走降级处理。
调用方多请求几次,就可以看到OnBreak的日记输出,说明断路器已经处于Open状态,不会直接走真正的请求,而是走的fallBACk。
最后启动服务A,可以看到OnReset的日记输出,说明断路器已经处于Closed状态了,浏览器显示的也是服务A的返回结果。
再来模拟一下超时的情形。
因为上面设置的超时时间是1秒,所以让其休息1001毫秒就可以模拟了。
// GET api/values [httpGet] public String Get() { System.Threading.Thread.Sleep(1001); return "service--a"; }
再来看看效果图
title="再探Circuit Breaker之使用Polly" alt="再探Circuit Breaker之使用Polly" src="https://cn.js-code.com/res/2019/02-08/23/031633582ef56aa102fbe1a67eee87c9.gif">
调用方一直是提示因为超时而降级,而熔断。从日记也可以看出,是因为超时而导致熔断的。
前面还提到一个注册服务的问题,这里解释一下为什么我们要让其注册成Singleton?
我们先把注册服务这一块调整为不是Singleton,这里以Scope为例,Transient也是一样的。
public void Configureservices(IserviceCollection services) { services.AddScoped(); //services.AddSingleton (); services.AddMvc(); }
效果如下:
title="再探Circuit Breaker之使用Polly" alt="再探Circuit Breaker之使用Polly" src="https://cn.js-code.com/res/2019/02-08/23/8e648c26b9abf234a54167222fe43c1f.gif">
可以看到,日记一直输出超时!并没有提示熔断相关的信息!这说明我们设置的熔断并没有起作用!!
这个问题与实例的生命周期有着密不可分的关系!
试想一下,如果每次请求,都创建一个Aservice的实例,同样的每次都会重新创建一个新的熔断器,那熔断还会生效吗?
反之,如果熔断器只有一个,那么无论发起多少次请求,它都是唯一的,所以它才能统计到有多少次异常,从而去触发熔断。
这也是一个我们需要特别注意的地方。不然一个不小心就入坑了。
Polly用起来还是比较简单,比较灵活的,我们可以组合多种不同的Policy来达到我们想要的结果。
本文的示例代码:
https://github.com/catcherwong/Demos/tree/master/src/CircuitBreakerDemo/Polly">CircuitBreakerDemo
以上是大佬教程为你收集整理的再探Circuit Breaker之使用Polly全部内容,希望文章能够帮你解决再探Circuit Breaker之使用Polly所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。