为什么熔断降级
在大型分布式架构中,一个用户的请求,可能是这样:
如果这个时候一个服务出现异常:
- 服务提供者不可用(硬件故障、程序bug、网络故障、用户请求量较大)
- 重试导致的流量过大
- 服务调用者使用同步调用,产生大量的等待线程占用系统资源,一旦线程资源被耗尽,调用者提供 的服务也会变成不可用状态
就会导致请求堆集从而出现整个服务不可用的问题。用古话来讲就是:千里之堤毁于蚁穴
在复杂的分布式架构的应用程序有很多的依赖,都会不可避免的出现服务故障等问题。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。
在分布式架构中,有一种解决方法,就是熔断机制。也就是说当下游服务因为访问压力过大或者其他原因导致响应变慢的时候,上游服务为了保护自己以及系统整体的可用性,可以暂时切断对于下游服 务的调用。
熔断在生活中也随处可见:
- 比如“跳闸”,当电压超过负荷时,开关会自动跳闸。从而防止出现电路烧毁带来的火灾。
- 比如股票市场的熔断,对于股票设置一个熔断价格,当价格触发到熔断点之后,交易会被暂停一段 时间。或者交易可以继续进行,但是报价会限制在一定的范围
什么是熔断降级
Sentinel熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断。那么怎么去判断资源是否处于稳定状态呢?
- 平均响应时间 ( DEGRADE_GRADE_RT ):当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒 级)均超过阈值( count ,以 ms 为单位),那么在接下的时间窗口( DegradeRule 中的 timeWindow ,以 s为单位)之内,对这个方法的调用都会自动地熔断(抛出 DegradeException )。注意 Sentinel 默认统计的 RT 上限是4900 ms,超出此阈值的都会算作 4900 ms,若需要变更此上限可以通过启动配置项
-Dcsp.sentinel.statistic.max.rt=xxx 来 配置。- 异常比例 ( DEGRADE_GRADE_EXCEPTION_RATIO ):当资源的每秒请求量 >= 5,并且每秒异常总数 占通过量的比值超过阈值( DegradeRule 中的 count )之后,资源进入降级状态,即在接下的时 间窗口( DegradeRule中的 timeWindow ,以 s 为单位)之内,对这个方法的调用都会自动地返 回。异常比率的阈值范围是 [0.0, 1.0] ,代表0% - 100%。
- 异常数 ( DEGRADE_GRADE_EXCEPTION_COUNT ):当资源近 1 分钟的异常数目超过阈值之后会进行 熔断。注意由于统计时间窗口是分钟级别的,若 timeWindow 小于 60s,则结束熔断状态后仍可能 再进入熔断状态。
熔断后的处理
BlockHandler
若本次访问被限流或服务降级,则调用blockHandler指定的接口。
全局处理:
package com.lx.global;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.lx.User;
/**
* description 服务降级和限流处理
*
* @author 流星
* @date 2022/8/24 22:08
*/
public class GlobalBlockHandler {
public static User blockMethod(Integer userId, String username, BlockException e){
return new User(-1,"block...",-1);
}
}
consumer调用逻辑:
FallBack
若本接口出现未知异常,则调用fallback指定的接口。
全局处理:
package com.lx.global;
import com.lx.User;
/**
* description TODO
*
* @author 流星
* @date 2022/8/24 22:10
*/
public class GlobalFallback {
public User fallbackMethod(Integer userId, String username, Throwable e){
return new User(-1,"fallback...",-1);
}
}
consumer调用逻辑:
附:Spring Cloud学习系列
Spring Cloud项目(一)——集成Nacos作为注册中心
Spring Cloud项目(二)——集成Nacos作为配置中心
Spring Cloud项目(三)——实现Nacos数据信息持久化到MySQL
Spring Cloud项目(四)——使用Ribbon作为负载均衡
Spring Cloud项目(五)——使用openFeign作为服务调用
Spring Cloud项目(六)——使用sentinel作为流量管理
Spring Cloud项目(七)——使用sentinel作为限流和熔断
Spring Cloud项目(八)——使用gateway作为服务网关