目录
Spring cloud 如何整合Sentinel 和Sentinel 控制台?
Sentinel @SentinelResource注解使用及属性详情
学习背景
常见的容错方案有哪些?
1. 超时
超时指设置服务调用的超时时间,当被调用方调用超时时,默认视为调用失败,释放线程资源;优点:避免了大量调用失败导致线程阻塞,从而使得CPU,内存资源不够的情况
2. 限流
限流就是根据服务器资源环境,设置最大的QPS,当请求超过QPS 时,拒绝请求
3. 仓壁模式
字面的理解就是被调用资源进行隔离解耦,这样才能在出问题时,不会导致相互影响;
4. 断路器
断路器又称熔断器,是在调用过程中,一定时间内发生的错误次数或者错误率达到我们设置的阈值,那么就会触发断路器,对方法进行保护;断路器又三种状态:全开,半开,关闭
断路器实现三态转换可以参考:https://blog.csdn.net/lihailin9073/article/details/110097130
Sentinel 学习
Sentinel 是什么?
Sentinel 是一个轻量级的流量控制、熔断降级的java 库
Spring cloud 如何整合Sentinel 和Sentinel 控制台?
整合Sentinel 需要在pom 文件中引入Sentinel 依赖就可以在Sentinel 客户端进行管理
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
应用端连接控制台的配置项
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8899 # 控制台的地址
client-ip: 127.0.0.1 #指定和控制台通信的地址,默认会自动注册一个ip地址
port: 8719 #指定和控制台通信的接口,默认是8719,如果8719被占用则依次+1,直到找到未被占用的端口
heartbeat-interval-ms: 10000 #指定控制台和服务端心跳发送周期
启动sentinel dashboard
java -jar -Dserver.port = 8899 sentinel-dashboard.jar
Sentinel 如何实现编码埋点?
@GetMapping("/test-code-sentinel")
public String testCodeSentinel(String a){
Entry entry = null;
try {
// 核心 SphU test-code-sentinel 是资源名称
entry = SphU.entry("test-code-sentinel");
// 被保护的资源
if (StringUtils.isEmpty(a)){
throw new NullPointerException("空指针异常");
}
return "b";
// 如果被保护的资源被限流或者降级就会抛出该异常
} catch (BlockException e) {
e.printStackTrace();
return "开始限流";
}catch (Exception e){
// 统计NPE 异常发生的次数,占比
Tracer.traceEntry(e,entry);
return "空指针异常降级";
}finally {
if (entry!=null){
entry.exit();
}
}
}
Sentinel @SentinelResource注解使用及属性详情
Sentinel 的注解是@SentinelResource ,通过注解中的定义属性,同样可以实现和编码埋点的同样操作。对于@SentinelResource 注解的详细属性及解释如下
entryType: entry类型,标记流量的方向,取值IN/OUT,默认是OUT
blockHandler 处理BlockException的函数名称。函数要求:
1. 必须是 public
2.返回类型与原方法一致
3. 参数类型需要和原方法相匹配,并在最后加 BlockException 类型的参数。
4. 默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法。
blockHandlerClass 存放blockHandler的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同blockHandler。
fallback 用于在抛出异常的时候提供fallback处理逻辑。fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。函数要求:
1. 返回类型与原方法一致
2. 参数类型需要和原方法相匹配,Sentinel 1.6开始,也可在方法最后加 Throwable 类型的参数。
3.默认需和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定fallbackClass里面的方法。
fallbackClass 存放fallback的类。对应的处理函数必须static修饰,否则无法解析,其他要求:同fallback。
defaultFallback 用于通用的 fallback 逻辑。默认fallback函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。若同时配置了 fallback 和 defaultFallback,以fallback为准。函数要求:
1. 返回类型与原方法一致
2. 方法参数列表为空,或者有一个 Throwable 类型的参数。
3. 默认需要和原方法在同一个类中。若希望使用其他类的函数,可配置 fallbackClass ,并指定 fallbackClass 里面的方法。
exceptionsToIgnore 指定排除掉哪些异常。排除的异常不会计入异常统计,也不会进入fallback逻辑,而是原样抛出。
RestTemplate 如何整合Sentinel ?
在RestTemplate 初始化Bean添加@SentinelRestTemplate 注解,及可满足RestTemplate整合Sentinel.
@Bean
@LoadBalanced
@SentinelRestTemplate
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
同时,Sentinel 还提供了开关配置,通过配置我们可以设定是否开启ResetTemplate Sentinel 整合
resttemplate:
sentinel:
enabled: true # true 表示开启Sentinel RestTemplate整合,false 反之
Feign 如何整合Sentinel?
在Feign 的配置中增加如何配置
feign:
# 开启feign 和sentinel 结合
sentinel:
enabled: true
Feign 整合Sentinel ,触发限流或者降级后,如何设置自定义处理逻辑?如果捕获异常呢?
在@FeignClient 接口提供了两个属性可以满足我们的要求,分别是
fallback 属性 Feign 触发限流或者降级后,定制处理逻辑,but 不能够捕获到异常。eg:
@FeignClient(value = "alibaba-nacos",
fallback = AlibabaNacosClientFallback.class
)
fallbackFactory 属性 比fallback 功能强大,可以捕获到异常
注意: fallback 属性和fallbackFactory 在使用过程中是互斥的,如果使用了fallback 则不能使用fallbackFactory.反之同理
Sentinel 如何实现持久化?
Sentinel 有一个痛点就是如果没有配置Sentinel 规则持久化,当应用服务重启后,配置的所有规则都会被清空。所以在生产上使用Sentinel需要配置Sentinel 的持久化或者使用ali 的AHAS 在线流量控制;对于Sentinel 的持久化实现可以参考这两个博文:
拉模式: http://www.imooc.com/article/289402
推模式: http://www.imooc.com/article/289464
Sentinel 配置项详解
Sentinel 配置项详解可以参考: http://www.imooc.com/article/289562
总结:
该博文基于参考大目老师spring cloud alibaba 课程做的相关总结,引用如下:
Alibaba Sentinel 规则参数总结
SentinelResource注解 属性总结
Alibaba Sentinel规则持久化-拉模式-手把手教程【基于文件】
Alibaba Sentinel规则持久化-推模式-手把手教程【基于Nacos】
Alibaba Sentinel 配置项总结