springcloudAlibaba_sentinel 熔断降级
概述
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
注意:本文档针对 Sentinel 1.8.0 及以上版本。1.8.0 版本对熔断降级特性进行了全新的改进升级,请使用最新版本以更好地利用熔断降级的能力。
sentinel作为断路器与其他断路器功能那个对比
Sentinel | Hystrix(维护状态) | Resilience4j(Spring推荐) | |
---|---|---|---|
开发者 | alibaba | Netflix | 独立 |
隔离策略 | 信号量隔离(并发线程数限流) | 线程池隔离/信号量隔离 | 信号量隔离 |
熔断降级策略 | 基于响应时间、异常比率、异常数 | 基于异常比率 | 基于异常比率、响应时间 |
实时统计实现 | 滑动窗口(LeapArray) | 滑动窗口(基于 RxJava) | Ring Bit Buffer |
动态规则配置 | 支持多种数据源 | 支持多种数据源 | 有限支持 |
扩展性 | 多个扩展点 | 插件的形式 | 接口的形式 |
基于注解的支持 | 支持 | 支持 | 支持 |
限流 | 基于 QPS,支持基于调用关系的限流 | 有限的支持 | Rate Limiter |
流量整形 | 支持预热模式、匀速器模式、预热排队模式 | 不支持 | 简单的 Rate Limiter 模式 |
系统自适应保护 | 支持 | 不支持 | 不支持 |
控制台 | 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 | 简单的监控查看 | 不提供控制台,可对接其它监控系统 |
githubstar(2020.6) | 12.6 | 19.8k | 5.6k |
熔断策略
Sentinel 提供以下几种熔断策略:
- 慢调用比例 (
SLOW_REQUEST_RATIO
):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。 - 异常比例 (
ERROR_RATIO
):当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0]
,代表 0% - 100%。 - 异常数 (
ERROR_COUNT
):当单位统计时长(statIntervalMs
)内请求数目大于设置的最小请求数目并且异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
注意异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException
)不生效。为了统计异常比例或异常数,需要通过 Tracer.trace(ex)
记录业务异常。示例:
|
|
开源整合模块,如 Sentinel Dubbo Adapter, Sentinel Web Servlet Filter 或 @SentinelResource
注解会自动统计业务异常,无需手动调用。
熔断降级规则说明
熔断降级规则(DegradeRule)包含下面几个重要的属性:
Field | 说明 | 默认值 |
---|---|---|
resource | 资源名,即规则的作用对象 | |
grade | 熔断策略,支持慢调用比例/异常比例/异常数策略 | 慢调用比例 |
count | 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值 | |
timeWindow | 熔断时长,单位为 s | |
minRequestAmount | 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) | 5 |
statIntervalMs | 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) | 1000 ms |
slowRatioThreshold | 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入) |
熔断器事件监听
Sentinel 支持注册自定义的事件监听器监听熔断器状态变换事件(state change event)。示例:
|
|
示例
慢调用比例
-
设置熔断降级规则
解释一下熔断降级规则,一秒钟内超过5次请求 && 慢调用(响应时间大于4ms的请求记为慢调用)比例大于阈值0.2 则打开熔断,熔断时长10s内所有请求被降级,10s后断路器进入半开状态,放一个请求进来,响应时间在4ms内则关闭熔断,否则继续打开熔断,10s之后再尝试。
-
设置jmeter,增大qps,让断路器打开熔断,报错的时候就打开了此时使用浏览器访问会得到一个sentinel返回的错误
也可以直接在程序中设置运行时间(sleep超过4ms)
1
Blocked by Sentinel (flow limiting)
-
关闭jmeter请求,等10s后再次访问浏览器,此时正常,因为不满足1s最小请求5次的条件
1
World Sentinel
异常比例
-
修改程序,使之异常
1 2 3 4 5 6 7 8 9 10
@RestController public class WorldController { @GetMapping(value = "/world") @SentinelResource("world") public String hello() { int i = 10/0; return "World Sentinel"; } }
-
配置降级规则为异常比例
当1s内请求次数超过5次 && 异常比例超过10% 则触发熔断,熔断时长为10s,10s后进入半打开状态,放一个请求进来,成功则关闭熔断,否则继续熔断10s后再次尝试。
-
先用jmeter访问,qops 10 触发熔断,此时用浏览器请求
1
Blocked by Sentinel (flow limiting)
-
10s后 再次用浏览器请求,会进入错误页面,因为不满足1s内最小5次请求的条件由应用程序进行处理,然后返回错误页面
异常数
-
程序和上面一样
-
配置降级规则
当1s内请求次数超过5次 && 异常数超过5次,则熔断,10s后关闭熔断再次尝试
-
使用jmeter访问触发熔断
-
使用浏览器访问报sentinel提示的错误
-
10s后再次访问报应用程序返回的错误界面