Sentinel断路器与熔断降级
前言
Sentinel的熔断降级通过断路器实现,本文通过介绍熔断器的定义、如何构建熔断器、断路器校验逻辑、断路器状态转换、异常/慢调用熔断流量是如何统计等方面梳理断路器的工作原理和实现方式。
一、断路器定义
Sentinel中的熔断降级使用断路器实现,先看下断路器概念,来自维基百科的定义:
断路器有分简单与较进阶的版本,简单的断路器只需要知道服务是否可用。而较进阶的版本比起前者更有效率。进阶的断路器带有至少三个状态:
关闭:断路器在预设的情形下是呈现关闭的状态,而断路器本身“带有”计数功能,每当错误发生一次,计数器也就会进行“累加”的动作,到了一定的错误发生次数断路器就会被“开启”,这个时候亦会在内部启用一个计时器,一旦时间到了就会切换成半开启的状态。
开启:在开启的状态下任何请求都会“直接”被拒绝并且抛出异常讯息。
半开启:在此状态下断路器会允许部分的请求,如果这些请求都能成功通过,那么就意味着错误已经不存在,则会被“切换回”关闭状态并“重置”计数。倘若请求中有“任一”的错误发生,则会回复到“开启”状态,并且重新计时,给予系统一段休息时间
说明:从概念中可以看出断路器的关键点在于统计流量与三种状态的转换。
二、构建断路器
我们通过DegradeRuleManager.loadRules或者getProperty().updateValue使降级规则生效时,会将DegradeRule转换为断路器CircuitBreaker。
断路器由两类构成,慢调用使用ResponseTimeCircuitBreaker,异常数和异常比例使用ExceptionCircuitBreaker。
断路器类图
三、断路器校验
DegradeSlot负责熔断规则的校验,tryPass方法执行具体的判断。
判断的逻辑
如果熔断器状态为关闭,则返回true,即允许请求通过。
如果熔断器状态为开启,并且已经超过熔断时长以及开启状态成功转换为半开启(探测)状态,则返回true,即允许请求通过。
如果熔断器状态为开启,并且还在熔断时长内,则返回false,禁止请求通过。
那探测和开启状态都允许请求通过,在“熔断降级说明”文章中知道,探测状态只允许一个请求通过,这个是在哪里控制的呢?
四、断路器状态转换
在调用Entry#exit()时,会触发插槽链条的退出调用。具体到熔断降级DegradeSlot#exit方法。通过circuitBreaker.onRequestComplete回调熔断器执行状态切换。
ExceptionCircuitBreaker负责异常数/异常比例的熔断,通过滑动窗口统计发生错误数及请求总数。
详细熔断逻辑
ResponseTimeCircuitBreaker负责慢调用的熔断,通过滑动窗口统计慢调用数量及总的请求数。
详细熔断逻辑
五、滑动窗口流量统计
异常熔断ExceptionCircuitBreaker的流量统计通过SimpleErrorCounterLeapArray实现,默认采样窗口sampleCount为1,统计区间intervalInMs为1秒。
慢调用熔断ResponseTimeCircuitBreaker的流量统计通过SlowRequestLeapArray实现,默认采样窗口sampleCount为1,统计区间intervalInMs为1秒。
说明:具体滑动窗口的统计逻辑见文章“Sentinel基于滑动窗口的流量统计【源码笔记】”。
作者介绍:;梁勇,哈罗出行高级技术专家,负责服务框架和消息平台,专注后端中间件方向,公众号“瓜农老梁”维护者。
本文分享自微信公众号 - 中间件兴趣圈(dingwpmz_zjj)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
缓存穿透、缓存击穿和缓存雪崩
作者 | xiaowei123 出处 | https://0x9.me/Lg9yp 在Redis缓存中有三个必须要知道概念:「缓存穿透、缓存击穿和缓存雪崩。」 缓存穿透 什么是缓存穿透呢?它是指当用户在查询一条数据的时候,而此时数据库和缓存却没有关于这条数据的任何记录,而这条数据在缓存中没找到就会向数据库请求获取数据。它拿不到数据时,是会一直查询数据库,这样会对数据库的访问造成很大的压力。 如:用户查询一个 id = -1 的商品信息,一般数据库 id 值都是从 1 开始自增,很明显这条信息是不在数据库中,当没有信息返回时,会一直向数据库查询,给当前数据库的造成很大的访问压力。 这时候我们要想一想,该如何解决这个问题呢?o(╥﹏╥)o 一般我们可以想到从缓存开始出发,想如果我们给缓存设置一个如果当前数据库不存在的信息,把它缓存成一个空对象,返回给用户。 ^_^没错,这是一个解决方案,也就是我们常说的缓存空对象(代码维护简单,但是效果不是很好)。 Redis 也为我们提供了一种解决方案,那就是布隆过滤器(代码维护比较复杂,效果挺好的)。 「那接下来,二哈先解释下这两种方案:」 缓存空对象...
- 下一篇
跨域请求产生错误的原因及处理方法
//每日前端夜话第428篇//正文共:1400字//预计阅读时间:6 分钟 如果你在开发网站时曾经尝试通过框架或是浏览器的 fetch、XHR 请求过外部 API 的话,那么一定遇到过跨域请求,还有那个触目惊心的 CORS 错误信息;今天咱们来讨论跨域问题的原因以及解决方法。 跨域请求 如果你没有没有遇过,可以试着在浏览器的 console 页输入下面的代码: constxhr=newXMLHttpRequest()xhr.onreadystatechange=()=>{if(xhr.readyState===4){console.log(xhr.status===200?xhr.responseText:'error')}}xhr.open('GET','https://google.com')xhr.send() 这段代码通过调用浏览器的 XMLHttpRequest 对 Google 发出请求,而得到的结果如图所示: 这就是跨域请求问题,当通过 JavaScript 对不同的来源发送请求时,这个请求的响应就会被浏览器拦截,不交给 JavaScript 处理。这里的“不同来源...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8编译安装MySQL8.0.19
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS6,CentOS7官方镜像安装Oracle11G