Sentinel

什么是Sentinel

Sentinel也是Spring Cloud Alibaba的组件

Sentinel英文翻译“哨兵/门卫”,限制并发数

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel以流量为切入点,从流量控制、熔断、降级、系统负载保护等多个维度保护服务的稳定性

为什么需要Sentinel

丰富的应用场景

双十一、秒杀、抢火车票等等

完备的实时状态监控

可以支持显示当前项目各个服务的运行和压力状态,分析出每台服务器处理的秒级别的数据

广泛的开源生态

很多技术可以和Sentinel进行整合,Spring Cloud、Dubbo,而且依赖少配置简单

完善的SPI的扩展

Sentinel支持程序设置各种自定义的规则
……

基本配置和限流效果

我们的限流针对的是控制器方法

我们在csmall-stock-webapi模块中进行测试和观察限流效果

添加sentinel的依赖

1
2
3
4
5
<!--添加sentinel依赖-->
       <dependency>
           <groupId>com.alibaba.cloud</groupId>
           <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
       </dependency>

application-dev.yml文件添加配置
1
2
3
4
5
6
7
spring:
cloud:
   #配置sentinel信息
  sentinel:
    transport:
      dashboard: localhost:8080 #配置sentinel仪表盘的位置
      port: 8721 #执行限流的端口,每个项目是唯一的,如果此项目使用了8721端口,其余就不能使用该端口了

下面进行限流操作

在要流行的控制器方法前添加注解

1
2
3
4
5
6
7
8
9
10
@PostMapping("/reduce/count")
   @ApiOperation("减少库存方法")
   // @SentinelResource注解标记的控制器方法,会被sentinel进行管理
   // 在这个方法第一次运行后,可以在sentinel仪表盘界面中设置限流规则
   // "减少库存的方法"设置当前方法在仪表盘中显示的名称
   @SentinelResource("减少库存的方法")
   public JsonResult reduceCommodityCountStock(StockReduceCountDTO stockReduceCountDTO){
       stockService.reduceCommodityCount(stockReduceCountDTO);
       return JsonResult.ok("商品库存减少成功");
  }

启动sentinel

解压sentinel的压缩包到没有中文或空格的路径中

进入文件夹有两个文件:sentinel-dashboard-1.8.2.jarstart-sentinel.bat

可以直接双击:start-sentinel.bat

或者在dos窗口中运行以下命令

java -jar sentinel-dashboard-1.8.2.jar

访问路径是:http://localhost:8080/
image
输入用户名和密码,都是sentinel

启动stock模块,需要第一次运行控制方法后才能监控到该模块(为了观察效果记得时刻刷新页面)
image
image
image

QPS和并发线程数

QPS:是每秒请求数

单纯的限制在一秒内有多少个请求访问控制器方法

并发线程数:是当前服务器资源请求线程的数量

限制的是使用当前服务器的线程数

自定义限流方法和降级方法

所谓降级就是正常运行控制器方法的过程中,控制器方法发生异常,Sentinel支持我们运行别的方法来处理异常,或运行别的业务流程处理

StockController类中的@SentinelResource注解中,可以定义处理降级情况的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@PostMapping("/reduce/count")
   @ApiOperation("减少库存方法")
   // @SentinelResource注解标记的控制器方法,会被sentinel进行管理
   // 在这个方法第一次运行后,可以在sentinel仪表盘界面中设置限流规则
   // "减少库存的方法"设置当前方法在仪表盘中显示的名称
   //blockHandler指定请求被限流时运行的方法名
   //fallback指定控制器放啊发生异常时,要执行的降级方法名
   @SentinelResource(value = "减少库存的方法",blockHandler = "blockError",
   fallback = "fallbackError")
   public JsonResult reduceCommodityCountStock(StockReduceCountDTO stockReduceCountDTO){
       //模拟发生异常,进行降级
       if(Math.random()<0.5){
           throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"抛出随机异常!");
      }
       stockService.reduceCommodityCount(stockReduceCountDTO);
       return JsonResult.ok("商品库存减少成功");
  }
   //Sentinel自定义限流方法
   //限流方法一般直接返回限流信息即可
   //1.访问修饰符必须时public
   //2.返回值类型必须和限流的控制器方法一致
   //3.方法名称必须是@SentinelResource注解中blockHandler指定的方法名称
   //4.方法参数列表必须和限流的控制器方法一致,而且还要添加一个BlockException类型的参数
   public JsonResult blockError(StockReduceCountDTO stockReduceCountDTO, BlockException e){
       return JsonResult.failed(ResponseCode.BAD_REQUEST,"服务器繁忙,请稍后重试~");
  }
   //Sentinel自定义降级方法
   //降级方法一般直接返回降级信息即可
   //1.访问修饰符必须时public
   //2.返回值类型必须和限流的控制器方法一致
   //3.方法名称必须是@SentinelResource注解中fallback指定的方法名称
   //4.方法参数列表必须和限流的控制器方法一致
   public JsonResult fallbackError(StockReduceCountDTO stockReduceCountDTO){
       return JsonResult.failed(ResponseCode.BAD_REQUEST,"因为运行时发生异常,服务降级!!");
  }