Sentinel降级与热点参数限流规则
@toc
1、概述
除了流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。因此我们需要对不稳定的弱依赖服务调用进行熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。熔断降级作为保护自身的手段,通常在客户端(调用端)进行配置。
2、熔断策略
我看官网现在sentinel的文档是1.8的,和我现在1.7.2的文档有些许差别,你在使用的时候注意下自己的版本
3、@SentinelResource注解
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。 @SentinelResource 注解包含以下属性:
- value:资源名称,必需项(不能为空)
- entryType:entry 类型,可选项(默认为 EntryType.OUT)
- blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。fallback 函数签名和位置要求:
返回值类型必须与原函数返回值类型一致;
方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。 - defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。defaultFallback 函数签名要求:
返回值类型必须与原函数返回值类型一致;
方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。 - exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
注:1.6.0 之前的版本 fallback 函数只针对降级异常(DegradeException)进行处理,不能针对业务异常进行处理。
特别地,若 blockHandler 和 fallback 都进行了配置,则被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler
、fallback
和 defaultFallback
,则被限流降级时会将 BlockException
直接抛出。
4、熔断降级测试
测试使用的controller:
@RestController
@Slf4j
public class DemoController {
//blockHandler 使用sentinel进行不同规则控制时的默认处理方案
// fallback:自定义业务出错时默认处理方案
// defaultFallback 指定一个业务错误时默认方案
@GetMapping("/demo")
@SentinelResource(value = "aaaa",blockHandler = "blockHandler",fallback = "fallCustomer",defaultFallback = "defaultFall") //作用:代表这是一个sentinel资源
public String demo(Integer id){
log.info("demo ok...");
if(id<0){
throw new RuntimeException("id无效");
}
return "demo ok !!!";
}
@GetMapping("/test")
public String test(){
log.info("test ok...");
return "test ok !!!";
}
//
public String blockHandler(Integer id, BlockException e){
if(e instanceof FlowException){
return "当前请求过于火爆,您已被流控!!";
}
if(e instanceof DegradeException){
return "当前请求过于火爆,您已被降级!!";
}
if(e instanceof ParamFlowException){
return "当前请求过于火爆,您已被热点参数限流!!";
}
return "服务器快爆了,请稍后再试!!!";
}
//
public String defaultFall(){
return "默认处理:服务器出错了!!!";
}
public String fallCustomer(Integer id){
return "自定义服务器出错啦!!!";
}
}
上面的fallback属性和defaultFallback是我们指定业务代码中抛出异常的解决办法,优先执行fallback属性。
启动微服务之后,发现sentinel dashboard的/demo下面多了一个aaaa的资源(名字你随便起)
编辑降级规则
我的代码中写的是id小于0时会抛出异常,而我么能配置的降级规则中配置的是当异常数大于2时,会触发降级,时间间隔为30秒。
我们故意频繁出发异常,可以看到,此时已经出发降级,执行的是注解中的blockHandler = "blockHandler"
指定的blockHandler方法。
5、热点参数限流
5.1 配置热点参数限流
5.2 测试热点参数限流
若是正常的参数,则当阈值超过10(每秒处理的请求超过10)的时候限流,若是热点参数的时候,上图中我们配置的意思是当参数值为12或者14(也就是热点参数)的时候,限流阈值分别为1和3,直接触发限流。
先访问个正常的http://localhost:8998/demo?id=111
,多发送几次也没有触发限流。
访问热点参数
只访问一次,没有问题,因为我们当id=14配置的是每秒最多处理3个请求
但是,当我们频繁发送热点请求的时候,可以看到,已经被限流,并执行了 @SentinelResource
注解中blockHandler = "blockHandler"
所指定的方法。
限流规则还挺多的,系统规则,授权规则等等我还得慢慢摸索。
- 点赞
- 收藏
- 关注作者
评论(0)