Spring Cloud Alibaba:Sentinel之降级、热点限流与授权控制
在上一篇博客中,博主介绍了如何整合Sentinel
以及它的流控规则:
- Spring Cloud Alibaba:整合Sentinel & 流控规则详细介绍
本篇博客将会介绍Sentinel
的降级、热点限流与授权控制,需要创建Spring Cloud Alibaba
项目以及整合Sentinel
,这些在上面那篇博客中已经介绍过了,这里不再赘述。
降级
熔断策略
慢调用比例:选择慢调用比例作为熔断策略,需要设置允许的慢调用RT
(即最大的响应时间),若请求的响应时间大于它则统计该请求为慢调用。当单位统计时长内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,熔断器会打开(OPEN
状态),则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求响应时间小于设置的慢调用RT
,则结束熔断,若大于设置的慢调用RT
则会再次被熔断。这和Hystrix
的熔断策略差不多:
- Spring Cloud 之Hystrix初使用
- Spring Cloud 之Hystrix熔断器、Hystrix-Dashboard可视化监控中心
给资源添加降级。
为了测试,需要修改/kaven
接口:
@GetMapping("kaven")
public String getKaven(boolean sleep) throws InterruptedException {
if(sleep) {
Thread.sleep(400);
}
return "hello kaven " + messageService.getMessage();
}
启动应用后,先请求几次接口,让Sentinel
有展示数据,方便给资源添加降级。
当单位统计时长(100000ms=100s
,为了方便测试 )内请求数目大于设置的最小请求数目5
,并且慢调用的比例大于阈值20%
,熔断器会打开(OPEN
状态),则接下来的熔断时长(120s
)内请求会自动被熔断。经过熔断时长(120s
)后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求响应时间小于设置的慢调用RT
(300ms
),则结束熔断,若大于设置的慢调用RT
则会再次被熔断。
第6
次请求/kaven
接口被降级了(100s
内,慢调用的比例很显然是100%
)。
熔断时长(120s
)内请求会自动被熔断。
经过熔断时长(120s
)后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求响应时间小于设置的慢调用RT
(300ms
),则结束熔断。
异常比例:当单位统计时长内请求数目大于设置的最小请求数目,并且请求异常的比例大于阈值,熔断器打开(OPEN
状态),则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求访问接口成功,则结束熔断,否则会再次被熔断。异常比例的阈值范围是 [0.0, 1.0]
,代表0% - 100%
。
修改/kaven
接口:
@GetMapping("kaven")
public String getKaven(boolean throwExc) throws InterruptedException {
if(throwExc) {
throw new RuntimeException();
}
return "hello kaven " + messageService.getMessage();
}
重新启动应用,给资源添加降级。
第6
次请求/kaven
接口被降级了(100s
内,异常的比例很显然是100%
)。
熔断时长(120s
)内请求会自动被熔断。
经过熔断时长(120s
)后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求访问接口成功,则结束熔断。
异常数:当单位统计时长内的请求异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN
状态),若接下来的一个请求访问接口成功则结束熔断,否则会再次被熔断。将/kaven
资源的降级规则修改为如下图所示:
第6
次请求/kaven
接口会被降级,其他情况与上面两种熔断策略一样,这里不再赘述。
热点限流
修改/kaven
接口:
@GetMapping("kaven")
@SentinelResource("kaven")
public String getKaven(@RequestParam(value = "arg1", required = false) Integer arg1,
@RequestParam(value = "arg2", required = false) Integer arg2) {
return "hello kaven " + messageService.getMessage();
}
重新启动应用,给kaven
资源(不是/kaven
资源)添加热点限流。
给kaven
资源添加热点限流如下图所示,表示当请求的arg2
参数存在,且QPS
大于5
则触发限流(10s
内)。
第6
次请求/kaven
接口(每次都传入arg2
参数)会被限流(10s
内)。
如果不传入arg2
参数,请求超过5
次也不会被限流(10s
内),传入arg2
参数,只要携带arg2
参数的请求不超过5
次也不会被限流(10s
内)。
授权控制
添加两个配置类:
package com.kaven.alibaba;
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
public class RequestParametersLimiter implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest httpServletRequest) {
// 每个请求都会被校验参数中是否包含arg1
// 如果不包含则抛异常
if(httpServletRequest.getRequestURI().startsWith("/kaven")){
String name = httpServletRequest.getParameter("arg1");
if(StringUtils.isEmpty(name)){
throw new RuntimeException("arg1 is null");
}
return name;
}
return "";
}
}
RequestParametersLimiter
类可以看作一个请求参数限制器,如果请求的URI
以/kaven
开头,当arg1
参数不存在时,会抛出异常,当arg1
参数存在时,直接返回该值,其他URI
的请求直接返回""
。
package com.kaven.alibaba;
import com.alibaba.csp.sentinel.adapter.servlet.callback.WebCallbackManager;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
@Configuration
public class SentinelConfiguration {
@PostConstruct
public void init(){
WebCallbackManager.setRequestOriginParser(new RequestOriginParserDefinition());
}
}
@PostConstruct
注解用于需要在依赖注入完成后执行任何初始化的方法。必须在类投入使用之前调用此方法。所有支持依赖注入的类都必须支持这个注解。@PostConstruct
注解的方法将会在依赖注入完成后被自动调用。WebCallbackManager
类是Sentinel
提供的URL cleaner
和URL block handler
的注册表。通过WebCallbackManager
类将RequestOriginParserDefinition
实例进行注册(请求源解析器,而其实现是一个请求参数限制器)。
重新启动应用,给资源添加授权。
因此,请求/kaven
接口时,arg1
参数的值只有属于[0,9]
区间才可以请求成功(黑名单相反)。
效果符合预期,Sentinel
的降级、热点限流与授权控制就介绍到这里,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。