Spring Cloud Alibaba Sentinel学习笔记
Sentinel支持流量控制、熔断降级、
一、控制台(Dashboard)
mvn clean package
也可以把项目导入idea打包。
- 运行jar包。
前提:jdk1.8+,端口未被占用。
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
# 在后台运行,日志输入到logs/sentinel.log
nohup java -jar sentinel-dashboard.jar > logs/sentinel.log 2>&1 &
通过-Dserver.port指定启动端口。
- 访问web界面:http:localhost:8080
登录用户名密码默认都是sentinel;
可以在配置文件添加配置以自定义登录用户名密码
也可以在启动时添加参数来自定义登录用户名密码
-Dsentinel.dashboard.auth.username=sentinel # 用于指定控制台的登录用户名为 sentinel
-Dsentinel.dashboard.auth.password=123456 # 用于指定控制台的登录密码为 123456
-Dserver.servlet.session.timeout=7200 # 用于指定 Spring Boot 服务端 session 的过期时间为7200 秒,60m 表示 60 分钟,默认为 30 分钟
二、客户端接入控制台
1、引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2、配置控制台
spring:
cloud:
sentinel:
transport:
port: 8719
dashboard: 192.168.10.128:8080
3、注意事项
- sentinel是懒加载机制,需要访问一次服务,才会接入控制台。
可以通过配置关闭懒加载机制
spring:
cloud:
sentinel:
eager: false
- 如果客户端与控制台不在同一台服务器,当两台服务器时间不一致时,无法使用实时监控。
三、流控规则
-
针对来源:sentinel可以针对不同调用者做不同的流控规则,填写微服务名,默认default,不区分来源。
-
QPS:每秒的请求数量。
-
流控模式:
直连:自身达到阈值,就对自己限流;
关联:当关联的资源达到阈值,就对自己限流【微服务级别的限流】;
链路:只记录指定链路上的流量,其他链路上的流量不计入限流规则内【api级别的限流】【针对来源是微服务级别的】 -
流控效果:
快速失败:直接失败,抛异常
Warm Up:根据coldFactor(冷加载因子,默认值为3),从阀值/coldFactor,经过预热时长,才达到设置的阀值。即如果阀值为100,冷加载因子为3,预热时长为10秒,那么就会用33(100/3)作为最初的阀值,经过10秒之后才会将阀值达到100,进而进行限流,意思就是让允许通过的流量缓慢增加,在达到一定的时间之后才达到阀值这样会更好的保护微服务。
排队等待:匀速排队,让请求以均匀的速度通过,阀值类型必须设置成QPS,否则无效。此种模式可适用于应对突发流量的场景
四、降级规则
- 慢调用比例 :可定义超时时长;
- RT:平均响应时间(毫秒)
- 比例阈值:0.0-1.0。
五、热点参数限流
热点参数限流官方文档
对请求参数带有热点参数的请求进行限流。
参数例外项,可以针对指定的参数值单独设置限流阈值,不受前面 count 阈值的限制。仅支持基本类型和字符串类型
六、系统规则
系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(EntryType.IN),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。
七、@SentinelResource
注意:注解方式埋点不支持 private 方法。
@SentinelResource 用于定义资源,并提供可选的异常处理和 fallback 配置项。
@SentinelResource 注解包含以下属性:
-
value:资源名称,必需项(不能为空)
-
entryType:entry 类型,可选项(默认为 EntryType.OUT)
-
blockHandler / blockHandlerClass: blockHandler 对应处理 BlockException 的函数名称,可选项。blockHandler 函数访问范围需要是 public,返回类型需要与原方法相匹配,参数类型需要和原方法相匹配并且最后加一个额外的参数,类型为 BlockException。blockHandler 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 blockHandlerClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。
-
fallback / fallbackClass:fallback 函数名称,可选项,用于在抛出异常的时候提供 fallback 处理逻辑。fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。
fallback 函数签名和位置要求:
1、返回值类型必须与原函数返回值类型一致;
2、方法参数列表需要和原函数一致,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
3、fallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。 -
defaultFallback(since 1.6.0):默认的 fallback 函数名称,可选项,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。默认 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,则只有 fallback 会生效。
defaultFallback 函数签名要求:
1、返回值类型必须与原函数返回值类型一致;
2、方法参数列表需要为空,或者可以额外多一个 Throwable 类型的参数用于接收对应的异常。
3、defaultFallback 函数默认需要和原方法在同一个类中。若希望使用其他类的函数,则可以指定 fallbackClass 为对应的类的 Class 对象,注意对应的函数必需为 static 函数,否则无法解析。 -
exceptionsToIgnore(since 1.6.0):用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。
1.8.0 版本开始,defaultFallback 支持在类级别进行配置。
特别地,若 blockHandler 和 fallback 都进行了配置,则未被限流降级之前会进入fallback,被限流降级而抛出 BlockException 时只会进入 blockHandler 处理逻辑。若未配置 blockHandler、fallback 和 defaultFallback,则被限流降级时会将 BlockException 直接抛出(若方法本身未定义 throws BlockException 则会被 JVM 包装一层 UndeclaredThrowableException)。
public class TestService {
// 原函数
@SentinelResource(value = "hello", blockHandler = "exceptionHandler", fallback = "helloFallback")
public String hello(long s) {
return String.format("Hello at %d", s);
}
// Fallback 函数,函数签名与原函数一致或加一个 Throwable 类型的参数.
public String helloFallback(long s) {
return String.format("Halooooo %d", s);
}
// Block 异常处理函数,参数最后多一个 BlockException,其余与原函数一致.
public String exceptionHandler(long s, BlockException ex) {
// Do some log here.
ex.printStackTrace();
return "Oops, error occurred at " + s;
}
// 这里单独演示 blockHandlerClass 的配置.
// 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中,并且必须为 public static 函数.
@SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
public void test() {
System.out.println("Test");
}
}
八、整合openFeign
- 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.2.2.RELEASE</version>
</dependency>
- 添加配置
# 开启sentinel对openfeign的支持
feign:
sentinel:
enabled: true
- 开启feign
在启动类加上注解
@EnableFeignClients
注:版本匹配
alibaba-2.2.1.RELEASE匹配openfeign-2.2.2.RELEASE,与openfeign-2.2.1.RELEASE不匹配
九、持久化
1、通过nacos
- 引入依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
- 修改配置文件
spring:
cloud:
sentinel:
datasource:
dsl:
nacos:
server-addr: 192.168.10.128:8848
dataId: ${spring.application.name}
groupId: DEFAULT_GROUP
data_type: json
rule_type: flow
- 在nacos添加配置
模板数据:
[
{
"resource": "sentinelTest",
"limitApp": "default",
"grade": 1,
"count": 1,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
说明:
- resource:资源名;
- limitApp:来源应用;
- grade:阈值类型:0=线程数,1=QPS;
- count:单机阈值;
- strategy:流控模式:0=直连,1=关联,2=链路;
- controlBehavior:流控效果:0=快速失败,1=Warm Up,2=排队等待;
- clusterMode:是否集群;