熔断策略主要以 CircuitBreaker 来完成、

工作原理

熔断器可以被看作为一个主要含有三个状态的状态机

如果以电路开关来看:

开关闭合对应 CLOSED 状态, 开关打开对应 OPEN 状态, 而 HALF OPEN 只是为了过渡处理过程中的状态变化

  • OPEN 状态, FLOW 不通
  • CLOSED 状态, FLOW 正常

CLOSED

熔断器的初始状态就是 CLOSED, 当熔断器状态为 CLOSED 的时候:

  • 所有通过策略的操作将会被执行, 熔断器也会记录这些操作的失败与成功
  • 如果通过策略执行的操作失败数到达某个设置的阈值,熔断器将会被熔断,即状态变更为 OPEN 。
    • CircuitBreaker 会在 N 次连续的操作失败被熔断
    • AdvancedCircuitBreaker 的熔断取决于失败比率
  • 对于改变熔断器状态的操作,此操作产生的原始 exception 将会被抛出, 而熔断器的状态将会变更为 OPEN

OPEN

当熔断器状态为 OPEN 的时候:

  • 所有通过策略的操作都不会被执行
  • 调用方会立刻被返回 BrokenCircuitException 异常
    • BrokenCircuitException 将包含最后试熔断器状态改变操作抛出的异常作为 InnerException
  • 熔断器打开之后, 会持续 durationOfBreak 参数配置的时间。在此时间结束之后,当下一个经过策略的操作执行或者当 CircuitState 熔断器状态被查询的时候, 熔断器的状态会变更为 HALF OPEN。

HALF OPEN

当熔断器状态为 HALF OPEN 的时候:

  • 下一个经过策略的操作将会被视作测试,用来检查熔断器的健康状态

    • 如果该操作执行的时候已经超过了 durationOfBreak 设置的熔断时间,则执行操作。熔断器在每次熔断的期间内 durationOfBreak,只允许有一次尝试操作。所有其他在 HALF OPEN 状态的操作都会被拒绝执行,并抛出 BrokenCircuitException 。
  • 传入 Execute() (或类似重载) 的委托方法将被尝试调用
    • 如果调用抛出了已处理的异常, 原本的异常将会被再次抛出,并且熔断器的状态会立即变更为 OPEN,持续 durationOfBreak 配置的时间。
    • 如果此操作未抛出异常,则熔断器状态变更为 CLOSED

流程图

Circuit Breaker

public static void TryBasic()
{
var breaker = Policy
// 设置熔断器处理的异常类型
.Handle<Exception>() // 设置异常阈值 3 ,熔断持续时间 5.5 秒
.CircuitBreaker(3, TimeSpan.FromSeconds(5.5),
(e, state, tspan, context)=>
{
Console.WriteLine($"OnBreak: state: {state} \r\n ex: {e.Message}");
},
context =>
{
Console.WriteLine("onReset");
},
()=>
{
Console.WriteLine("onHalfOpen");
}); var random = new Random();
var obj = Policy<object>
.Handle<Exception>()
.WaitAndRetryForever(
(times, tspan) => TimeSpan.FromSeconds(1),
(res, times, tspan, c) =>
{
Console.WriteLine($"retry: {times}, breaker state: {breaker.CircuitState}");
}) // 组合重试与熔断策略
.Wrap(breaker) .Execute(() =>
{
var val = random.Next(1, 100);
Console.WriteLine($"called:{val}");
switch (val % 9)
{
case 0:
return "Success";
default:
throw new Exception($"error val: {val}");
}
}); Console.WriteLine(obj);
}

输出:

熔断器初始化状态为 CLOSED, 在产生三次异常之后,触发 OnBreak 回调, 状态也变更为了 OPEN,

在上面我们设置的熔断持续时间结束后,状态变更为了 HALF OPEN, 由重试策略执行了一次 Execute ,

called: 20

因为由引发了一次异常,导致 CircuitBreaker 再次熔断, 状态变更为 OPEN,与流程图一致。

AdvancedCircuitBreaker

public static void TryAdvanced()
{
var breaker = Policy
.Handle<Exception>() // 设置高级熔断器
.AdvancedCircuitBreaker( // 设置超过30%的失败率则熔断
failureThreshold: 0.8, // 10 秒做一次采样
samplingDuration: TimeSpan.FromSeconds(10), // 在采样时间内最小吞吐量
minimumThroughput: 5, // 熔断持续时间
durationOfBreak: TimeSpan.FromSeconds(10),
onBreak: (e, state, tspan, context) =>
{
Console.WriteLine($"OnBreak: state: {state} \r\n ex: {e.Message}");
},
onReset: context =>
{
Console.WriteLine("onReset");
},
onHalfOpen: () =>
{
Console.WriteLine("onHalfOpen");
}); var random = new Random();
var obj = Policy<object>
.Handle<Exception>()
.WaitAndRetryForever(
(times, tspan) => TimeSpan.FromSeconds(1),
(res, times, tspan, c) =>
{
Console.WriteLine($"retry: {times}, breaker state: {breaker.CircuitState}");
})
.Wrap(breaker)
.Execute(() =>
{
var val = random.Next(1, 100);
Console.WriteLine($"called:{val}");
switch (val % 9)
{
case 0:
return "Success";
default:
throw new Exception($"error val: {val}");
}
}); Console.WriteLine(obj);
}

输出:

将采样时间内 samplingDuration 异常次数除以设置最小吞吐量 minimumThroughput,得到失败率,若超过设置的 failureThreshold,则触发熔断。

注意

使用 Wrap 方法组合两个或 更多策略一起监控 Execute 中执行的操作。

Polly 熔断策略的更多相关文章

  1. 微服务之Polly熔断策略

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

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

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

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

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

  4. Polly 重试策略

    工作原理 Retry 基本重试: public static void Retry() { var random = new Random(); // Policy<> 泛型定义返回值类型 ...

  5. .NET Core微服务之基于Polly+AspectCore实现熔断与降级机制

    Tip: 此篇已加入.NET Core微服务基础系列文章索引 一.熔断.降级与AOP 1.1 啥是熔断? 在广义的解释中,熔断主要是指为控制股票.期货或其他金融衍生产品的交易风险,为其单日价格波动幅度 ...

  6. ASP.NET Core 微服务初探[2]:熔断降级之Polly

    当我们从单体架构迁移到微服务模式时,其中一个比较大的变化就是模块(业务,服务等)间的调用方式.在以前,一个业务流程的执行在一个进程中就完成了,但是在微服务模式下可能会分散到2到10个,甚至更多的机器( ...

  7. (5)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- 熔断降级(Polly)

    一. 什么是熔断降级 熔断就是“保险丝”.当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成“雪崩”,或者大量的超时等待导致系统卡死. 降级的目的是当某个服务提供者发 ...

  8. (5).NET CORE微服务 Micro-Service ---- 熔断降级(Polly)

    一. 什么是熔断降级 熔断就是“保险丝”.当出现某些状况时,切断服务,从而防止应用程序不断地尝试执行可能会失败的操作给系统造成“雪崩”,或者大量的超时等待导致系统卡死. 降级的目的是当某个服务提供者发 ...

  9. 熔断降级(Polly)

    熔断降级(Polly) https://www.cnblogs.com/qhbm/p/9224307.html 一. 什么是熔断降级 熔断就是"保险丝".当出现某些状况时,切断服务 ...

随机推荐

  1. MongoDB Schema Design

    Normalization: ...... Relationships: One-to-One relationship: 1-to-many: many-to-many:

  2. springcloud第八步:hystrix解决服务雪崩

    断路器(Hystrix) 为什么需要 Hystrix? 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用(RPC).为了保证其高可用,单个服务又必须集群部署.由于网络原因或者自 ...

  3. linux 查看是否安装了MySQL

    yum 安装mysql      yum -y install mysql-server ------------------------------------------------------- ...

  4. Xgboost总结

    从决策树.随机森林.GBDT最终到XGBoost,每个热门算法都不是孤立存在的,而是基于一系列算法的改进与优化.决策树算法简单易懂可解释性强,但是过拟合风险很大,应用场景有限:随机森林采用Baggin ...

  5. httpappplication 和 httpmodule 的理解(转载,写的很好)

    第一部分:转载自Artech  IIS与ASP.NET管道 ASP.NET管道 以IIS 6.0为例,在工作进程w3wp.exe中,利用Aspnet_ispai.dll加载.NET运行时(如果.NET ...

  6. 谷歌将一些弱小的库从安卓代码移除Google Removes Vulnerable Library from Android

    Google this week released the November 2018 set of security patches for its Android platform, which ...

  7. Markdown学习示例

    Markdown学习示例 什么是Markdown Markdown是一种在web显示带样式风格文本的方式.你能通过它控制文本的字体样式.插入图片.插入列表等.通常,Markdown使用一些特殊的非字母 ...

  8. Spring AOP capabilities and goals

    Spring AOP 是用纯JAVA 实现的. 不需借助JAVA代码在编译处理阶段来实现. Spring 是在运行期实现的.AOP的实现可以在编译,加载,运行三个阶段来实现:Spring AOP 也不 ...

  9. supervisor配置详解(转)

    有阵子没写博客了,这段时间一直在研究python django框架和前端相关的东西.楼主学通信的,对web这一块啥也不懂,学了一个礼拜django,接着学了2个礼拜前端,感觉还是做不出来一个好看的页面 ...

  10. RESTful API 最佳实践----转载阮一峰

    文章地址http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html