依赖服务不稳定,造成响应的时间变长,让线程堆积,最终可能导致服务雪奔,熔断就是解决这个问题,
慢调用比例 (SLOW_REQUEST_RATIO
):
异常比例 (ERROR_RATIO
):
异常数 (ERROR_COUNT
)
Sentinel在1.8.0版本对熔断降级做了大的调整,可以定义任意时长的熔断时间,引入了半开启恢复支持。下面梳理下相关特性。
状态 | 说明 |
---|---|
OPEN | 表示熔断开启,拒绝所有请求 |
HALF_OPEN | 探测恢复状态,如果接下来的一个请求顺利通过则表示结束熔断,否则继续熔断 |
CLOSE | 表示熔断关闭,请求顺利通过 |
熔断降级规则包含下面几个重要的属性:
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 引入) |
官方文档网址: https://sentinelguard.io/zh-cn/docs/circuit-breaking.html
选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(
statIntervalMs
)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。
自己理解:在单位时间内的请求,响应的时间大于最大响应时间的比例大于阈值,并且最小请求书大于设置次数,就会触发熔断策略,在熔断时间内属于半开启状态,如果再次请求过来小于最大响应时间,则恢复,如果还是大于最大响应时间则继续熔断
//FlowLimitController.java
@GetMapping("/testC")
public String testC(){
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "----testC";
}
当单位统计时长(
statIntervalMs
)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是[0.0, 1.0]
,代表 0% - 100%。
自己理解:1QPS的请求数>5,并且异常比例大于阈值,就会触发
@GetMapping("/testD")
public String testD(Integer id){
if(id != null && id > 1){
throw new RuntimeException("异常比例测试");
}
return "------------testD";
}
:当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。
会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效
官网:https://sentinelguard.io/zh-cn/docs/parameter-flow-control.html
使用热点限流必须搭配sentinelResource注解
Sentinel 提供了 @SentinelResource 注解用于定义资源,它有很多的参数,我们这里主要关注两个参数:
@GetMapping("/testHotKey")
@SentinelResource("testHotKey")
public String testHotKey(
@RequestParam(value = "hot1",required = false) String hot1,
@RequestParam(value = "hot2",required = false) String hot2,
@RequestParam(value = "hot3",required = false) String hot3
){
return "-----testHotKey";
}
测试,此时如果我们传入参数hot1,并且超过阈值,就会出现限流,但是此时的限流效果为报错,显示不友好
@SentinelResource(value=“xxx”,blockHandler=“xxx”)
@GetMapping("/testHotKey")
@SentinelResource(value = "testHotKey",blockHandler = "block_hotKey")
public String testHotKey(
@RequestParam(value = "hot1",required = false) String hot1,
@RequestParam(value = "hot2",required = false) String hot2,
@RequestParam(value = "hot3",required = false) String hot3
){
return "-----testHotKey";
}
//处理异常方法,方法签名要和对应的接口方法保持一致
public String block_hotKey(String hot1, String hot2, String hot3, BlockException blockException){
return "系统繁忙请稍后再试";
}
显示结果
表示对参数进行更加细粒度话的配置,会根据参数的值,定义不同的限流规则
定义热点规则,当hot1值为5的时候,将阈值设置为200,注意:参数类型必须与热点参数的类型一致
2. 测试结果
当参数值为1的时候,阈值为1 当参数值为5的时候,阈值为200,因此参数为1的时候,会报异常,参数为5的时候不会