1 sentinel简介
1.1 sentinel解决的问题
- 雪崩问题:微服务调用链路中的某个服务故障,引起整个链路中的所有微服务都不可用,这就是雪崩。
解决雪崩问题的常见方式有四种: - 超时处理:设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休止等待。
- 舱壁模式:限定每个业务能使用的线程数,避免耗尽整个tomcat的资源,因此也叫线程隔离。
- 熔断降级:由断路器统计业务执行的异常比例,如果超出阈值则会熔断该业务,拦截访问该业务的一切请求。
- 流量控制:限制业务访问的QPS,避免服务因流量的突增而故障。
1.2 服务保护技术对比
2 微服务整合sentinel
2.1 引入sentinel依赖
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.2 配置控制台地址:
# Spring
spring:
application:
# 应用名称
name: ruoyi-gateway
profiles:
# 环境配置
active: dev
cloud:
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8718 # 配置sentinel地址与之产生联系
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-ruoyi-gateway
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow
- 访问微服务的任意端点,即可触发sentinel监控!
3 限流规则
- 簇点链路:就是项目内的调用链路,链路中被监控的每个接口就是一个资源。默认情况下sentinel会监控SpringMVC的每个端点(Endpoint),因此SpringMVC的美一个端点(Endpoint)就是调用链路中的一个资源。
- 流控、熔断等都是
针对簇点链路中的资源
来设置的,因此我们可以点击对应资源后面的按钮来设置规则:
- 点击流控
3.1 流控模式
- 直接:对当前资源限流
- 关联:高优先级资源触发阈值,对低优先级资源限流。
- 链路:阈值统计时,只统计从指定资源进入当前资源的请求,是对请求来源的限流
3.2 流控效果
- 快速失败:QPS超过阈值时,拒绝新的请求
- warm up:QPS超过阈值时,拒绝新的请求;QPS阈值是逐渐提升的,可以避免冷启动时高并发导致服务宕机。
- 排队等待:请求会进入队列,按照阈值允许的时间间隔依次执行请求;如果请求预期等待时长大于超时时间,直接拒绝
4 隔离和降级
4.1 Feign整合Sentinel
- yml文件开启Feign的Sentinel功能
# feign 配置
feign:
sentinel:
enabled: true
4.2 给FeignClient编写失败后的降级逻辑
- 方式一:FallbackClass,无法对远程调用的异常做处理
- 方式二:FallbackFactory,可以对远程调用的异常做处理
4.2.1 在feign-api项目中定义类,实现FallbackFactory,并加@Component注解,将RemoteFileFallbackFactory 注入到Spring中
@Component
public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class);
@Override
public RemoteFileService create(Throwable throwable)
{
log.error("文件服务调用失败:{}", throwable.getMessage());
return new RemoteFileService()
{
@Override
public R<SysFile> upload(MultipartFile file)
{
return R.fail("上传文件失败:" + throwable.getMessage());
}
};
}
}
4.2.2 在feign-api项目中的RemoteFileService接口中,使用RemoteFileFallbackFactory,即添加fallbackFactory = RemoteFileFallbackFactory.class
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class)
public interface RemoteFileService
{
/**
* 上传文件
*
* @param file 文件信息
* @return 结果
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
}
4.3 线程隔离
线程隔离有两种方式实现:
- 线程池隔离:基于线程池模式,有额外开销,但隔离控制更强
- 信号量隔离(Sentinel默认采用):基于计数器模式,简单,开销小
4.4 熔断降级
sentinel熔断降级的策略
- 慢调用比例:超过指定时长的调用为慢调用,统计单位时长内慢调用的比例,超过阈值则熔断
- 异常比例:统计单位时长内异常调用的比例,超过阈值则熔断
- 异常数:统计单位时长内异常调用的次数,超过阈值则熔断
4.5 授权规则
授权规则可以对调用的来源做控制,有白名单和黑名单两种方式
- 白名单:来源(origin)在白名单内的调用者允许访问
- 黑名单:来源(origin)在黑名单内的调用者不允许访问
5 规则持久化
Sentinel的控制台规则管理有三种模式:
- 原始模式:Sentinel的默认模式,将规则保存在内存,重启服务会丢失。
- pull模式:控制台将配置的规则推送到sentinel客户端,而客户端会将配置规则保存在本地文件或数据库中。以后会
定时
去本地文件或数据库中查询,更新本地规则。 - push模式:控制台将配置规则推送到远程配置中心,例如Nacos。Sentinel客户端监听Nacos,获取配置变更的推送消息,完成本地配置更新。
5.1 引入依赖
<!-- Sentinel Datasource Nacos 规则持久化-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
5.2 配置文件
# Spring
spring:
cloud:
sentinel:
# 取消控制台懒加载
eager: true
transport:
# 控制台地址
dashboard: 127.0.0.1:8718
# nacos配置持久化
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
dataId: sentinel-ruoyi-gateway # 配置id
groupId: DEFAULT_GROUP
data-type: json
rule-type: flow # 还可以是:degrade(降级)、authority(授权)、param-flow(热点参数限流)