Sentinel 除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。由于调用关系的复杂性,如果调用链路中的某个资源不稳定,最终会导致请求发生堆积。Sentinel 熔断降级会在调用链路中某个资源出现不稳定状态时(例如调用超时或异常比例升高),对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联错误。当资源被降级后,在接下来的降级时间窗口之内,对该资源的调用都自动熔断(默认行为是抛出 DegradeException
)。
降级策略
- 平均响应时间 (
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,则结束熔断状态后仍可能再进入熔断状态。
注意:异常降级仅针对业务异常,对 Sentinel 限流降级本身的异常(BlockException
)不生效。
1、依赖包 和 配置
<!-- spring-cloud-starter-alibaba-sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
#====================================================
spring.application.name: SpringBootWeb
#server
server.port=80
server.servlet.context-path=/
#sentinel控制台
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
#sentinel数据源连接nacos ds1为数据源的名称,可以随便写 , 限流配置
spring.cloud.sentinel.datasource.ds1.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds1.nacos.dataId=${spring.application.name}-sentinel-flow
spring.cloud.sentinel.datasource.ds1.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds1.nacos.ruleType=flow
#sentinel ,熔断降级配置
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=localhost:8848
spring.cloud.sentinel.datasource.ds2.nacos.dataId=${spring.application.name}-sentinel-degrade
spring.cloud.sentinel.datasource.ds2.nacos.groupId=DEFAULT_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.ruleType=degrade
2、测试代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
@RestController
public class HelloController {
@Autowired
private HelloService helloService ;
// 限流
@RequestMapping("/helloworld")
public String helloworld() {
return helloService.helloworld() ;
}
// 限流
@RequestMapping("/helloworld2/{name}")
public String helloworld2(@PathVariable("name") String name) {
return helloService.helloworld2(name) ;
}
// 熔断降级
@SentinelResource(value="helloworld3",fallback="helloworld3Fallback")
@RequestMapping("/helloworld3")
public String helloworld3() {
try {
Thread.sleep(100);
} catch (Exception e) {
}
return "hello Sentinel333 !" ;
}
// 该方法降级处理函数,参数要与原函数helloworld3相同,并且返回值类型也要与原函数相同,此外,该方法必须与原函数在同一个类中
public String helloworld3Fallback(){
return "hello Sentinel333 ! fallback ";
}
}
3、使用nacos持久化 配置
在nacos-server中添加配置,
resource : 资源名称 ;
grade : 0 根据RT(相应时间)降级,1根据异常比例降级,2根据异常数降级 , 参考RuleConstant.java
timeWindow:时间窗口,单位s(秒) ,达到降级条件后,接下来timeWindow 秒内的请求都会自动熔断,grade为2时注意时长 ;
count :阈值。 当grade为0时,单位ms(毫秒),当 1s 内持续进入 5 个请求,对应时刻的平均响应时间(秒级)均超过阈值(
count
,以 ms 为单位)时,进入熔断降级;当grade为1时,值的范围为
[0.0, 1.0]
,代表 0% - 100% , 当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值超过阈值(DegradeRule
中的count
)之后,资源进入降级状态;当grade为2时,值为整数,当资源近 1 分钟的异常数目超过阈值之后会进行熔断。注意由于统计时间窗口是分钟级别的,若
timeWindow
小于 60s,则结束熔断状态后仍可能再进入熔断状态。
[
{
"resource": "helloworld3",
"count": 20.0,
"grade": 0,
"timeWindow": 10
}
]
sentinel-dashborad可以看下相关配置。
4、测试,为了显示效果,在代码里面加上了 “Thread.sleep(100); ”
一直刷新请求,马上就会进入降级,持续降级10秒,然后正常几次后又进入降级状态