介绍
分布式系统的流量防卫兵
- Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。所以主要功能就是出入口流量控制
功能
流量控制
对于系统来说,任意时间到来的请求往往是随机不可控的,而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制
- 角度
- 资源的调用关系,例如资源的调用链路,资源和资源之间的关系
- 运行指标,例如 QPS、线程池、系统负载等
- 控制的效果,例如直接限流、冷启动、排队等
熔断降级
当检测到调用链路中某个资源出现不稳定的表现,例如请求响应时间长或异常比例升高的时候,则对这个资源的调用进行限制,让请求快速失败,避免影响到其它的资源而导致级联故障。
- 手段
- 通过并发线程数进行限制 :当线程数在特定资源上堆积到一定的数量之后,对该资源的新请求就会被拒绝。堆积的线程完成任务后才开始继续接收请求。
- 通过响应时间对资源进行降级:当依赖的资源出现响应时间过长后,所有对该资源的访问都会被直接拒绝,直到过了指定的时间窗口之后才重新恢复。
系统负载保护
- 系统自适应限流
配置环境
gradle依赖
- 基于Spring cloud、AOP,使用注解
compile'com.alibaba.cloud:spring-cloud-starter-alibaba-sentinel:2.1.0.RELEASE'
compile group: 'com.alibaba.csp', name: 'sentinel-transport-simple-http', version: '1.6.3'
控制台
一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。
- 提供web界面,可视化资源和流量监控、对资源埋点进行配置
- 参考 https://github.com/alibaba/Sentinel/wiki/控制台
熔断降级使用
使用注解
Sentinel 提供了 @SentinelResource 注解用于定义资源,并提供了 AspectJ 的扩展用于自动定义资源、处理 BlockException等
- 应用使用 Spring AOP,通过配置的方式将 SentinelResourceAspect 注册为一个 Spring Bean
@Configuration
public class SentinelAspectConfiguration {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}
@SentinelResource
用于定义资源,并提供可选的异常处理和 fallback 配置项 @SentinelResource 注解包含以下属性
- value:资源名称,必需项(不能为空)
- entryType:entry 类型,可选项EntryType.OUT/EntryType.IN(默认为 EntryType.OUT),对应入口控制/出口控制
- blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称。
- fallback:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理
- 返回值类型必须与原函数返回值类型一致
- fllback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
- defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。函数签名和fallback一致
- exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
- 示例
// 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 static 函数
@Override
@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {
ExceptionUtil.class})
public void test() {
log.info("Test");
}
@Override
@SentinelResource(value = "sayHi",blockHandler = "exceptionHandler", fallback = "helloFallback")
public String sayHi(long time) {
if (time < 0) {
throw new IllegalArgumentException("invalid arg");
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
throw new IllegalArgumentException("inter arg");
}
return String.format("Hello time %d", time);
}
@Override
@SentinelResource(value = "helloAnother", defaultFallback = "defaultFallback",
exceptionsToIgnore = {IllegalStateException.class})
public String helloAnother(String name) {
if (name == null || "bad".equals(name)) {
throw new IllegalArgumentException("oops");
}
if ("foo".equals(name)) {
throw new IllegalStateException("oops");
}
return "Hello, " + name;
}
// Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
public String helloFallback(long s, Throwable ex) {
log.error("fallbackHandler:" + s);
return "Oops fallbackHandler, error occurred at " + s;
}
public String defaultFallback() {
log.info("Go to default fallback");
return "default_fallback";
}
// Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
public String exceptionHandler(long s, BlockException ex) {
// Do some log here.
return "Oops,exceptionHandler, error occurred at " + s;
}
降级策略
- 平均响应时间 (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 控制台,在控制台上直接配置熔断降级规则。
- 打开控制台界面,点击簇点链路,选择程序里的埋点,点击降级
- 配置降级规则
- 使用
- 配置RT模式测试,控制台输入RT和窗口时间
- url:ip:port/sayHi?t=delayTime, 当 1s 内持续进入 5 个请求 平均delayTime>RT 进入降级服务
- 配置异常比例,控制台输入异常比例
- url:ip:port/baz/bad, 当资源的每秒请求量 >= 5,并且每秒异常总数占通过量的比值设定的异常比例 将在接下来设置的窗口时间内进入降级服务
- 配置RT模式测试,控制台输入RT和窗口时间