Sentinel限制并发数
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
7spring:
cloud:
#配置sentinel信息
sentinel:
transport:
dashboard: localhost:8080 #配置sentinel仪表盘的位置
port: 8721 #执行限流的端口,每个项目是唯一的,如果此项目使用了8721端口,其余就不能使用该端口了
下面进行限流操作
在要流行的控制器方法前添加注解1
2
3
4
5
6
7
8
9
10
// @SentinelResource注解标记的控制器方法,会被sentinel进行管理
// 在这个方法第一次运行后,可以在sentinel仪表盘界面中设置限流规则
// "减少库存的方法"设置当前方法在仪表盘中显示的名称
public JsonResult reduceCommodityCountStock(StockReduceCountDTO stockReduceCountDTO){
stockService.reduceCommodityCount(stockReduceCountDTO);
return JsonResult.ok("商品库存减少成功");
}
启动sentinel
解压sentinel的压缩包到没有中文或空格的路径中
进入文件夹有两个文件:sentinel-dashboard-1.8.2.jar
、start-sentinel.bat
可以直接双击:start-sentinel.bat
或者在dos窗口中运行以下命令
java -jar sentinel-dashboard-1.8.2.jar
访问路径是:http://localhost:8080/
输入用户名和密码,都是sentinel
启动stock模块,需要第一次运行控制方法后才能监控到该模块(为了观察效果记得时刻刷新页面)
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
// @SentinelResource注解标记的控制器方法,会被sentinel进行管理
// 在这个方法第一次运行后,可以在sentinel仪表盘界面中设置限流规则
// "减少库存的方法"设置当前方法在仪表盘中显示的名称
//blockHandler指定请求被限流时运行的方法名
//fallback指定控制器放啊发生异常时,要执行的降级方法名
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,"因为运行时发生异常,服务降级!!");
}