SpringCloud Alibaba 之Sentinel
实现熔断和限流
Sentinel是什么
官网 https://github.com/alibaba/Sentinel
中文 https://github.com/alibaba/Sentinel/wiki/%E4%BB%8B%E7%BB%8D
Hystrix 缺点
-
需要我们程序员自己手工搭建监控平台
-
没有一套web界面可以给我们进行更加细粒化的配置
流控、速率控制、服务熔断、服务降级…
Sentinel 单独一个组件,可以独立出来。
直接界面化的细粒度统一配置。
去哪儿下? https://github.com/alibaba/Sentinel/releases
此次下载 1.7.0 版本
能干嘛?
怎么玩?
查看github上官方文档可以看How to Use Sentinel
服务使用中的各种问题
服务雪崩
服务降级
服务熔断
服务限流
安装Sentinel控制台
sentinel组件由2部分构成:
后台
前台8080
核心库:(java客户端)不依赖任何框架/库,能够运行于所有Java运行时环境,同时对 Dubbo / Spring Cloud等框架也有较好的支持
控制台 :(Dashboard)基于 Spring Boot开发,打包后可以直接运行,不需要额外的Tomcat等应用容器。
安装步骤
下载 https://github.com/alibaba/sentinel/releases
下载到本地 sentinel-dashboard-1.7.0.jar
运行命令
前提: java8环境OK 8080端口不能被占用
命令: java -jar sentinel-dashboard-1.7.0.jar 在jar包文件夹cmd,输入
访问sentinel管理界面
http://localhost:8080
登录账号密码为sentinel
初始化演示工程
1、启动Nacos8848成功 : http://localhost:8848/nacos/#/login
2、Module cloudalibaba-sentinel-service8401
POM
<dependencies>
<!--SpringCloud alibaba nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--SpringCloud alibaba sentinel - datasource-nacos 后续做持久化用到-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<!--SpringCloud alibaba sentinel-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--openfeign 后续要用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--SpringBoot 整合Web组件+actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
YML
server:
port: 8401
spring:
application:
name: cloudalibaba-sentinel-service
cloud:
nacos:
discovery:
#Nacos服务注册中心地址
server-addr: localhost:8848
sentinel:
transport:
#配置Sentinel dashboard地址
dashboard: localhost:8080
#默认8719端口,假如被占用会自动从8719开始依次+1扫描,直至找到未被占用的端口
port: 8719
management:
endpoints:
web:
exposure:
include: '*'
主启动类
@EnableDiscoveryClient
@SpringBootApplication
public class MainApp8401 {
public static void main(String[] args) {
SpringApplication.run(MainApp8401.class, args);
}
}
业务类 FlowLimitController
@RestController
public class FlowLimitController {
@GetMapping("/testA")
public String testA() {
return "------testA";
}
@GetMapping("/testB")
public String testB() {
return "-----testB";
}
}
3、启动Sentinel8080
java -jar sentinel-dashboard-1.7.0.jar
4、启动微服务8401
5、启动8401微服务后查看sentinel控制台
会发现后台空空如也,啥都没有
Sentinel采用懒加载说明
执行一次访问即可 :http://localhost:8401/testA
http://localhost:8401/testB
效果 :应用开始出现在后台
结论:Sentinel8080正在监控
流控规则
流控规则简介
资源名:唯一名称,默认请求路径
针对来源:Sentinel可以针对调用者进行限流,填写微服务名,默认default(不区分来源)
阈值类型/单机阈值:
QPS(每秒钟的请求熟路):当调用该api的QPS达到阈值的时候,进行限流
线程数:当调用该api的线程数达到阈值时候,进行限流
是否集群:不需要集群
流控模式:
直接:api达到限流条件时,直接限流
关联:当关联的资源达到阈值时,就限流自己
链路:只记录指定链路上的流量(指定资源从入口资源进来的流量,如果达到阈值,就进行限流)
流控效果:
快速失败: 直接失败,抛异常
Warm Up: 根据codeFactor (冷加载因子,默认3)的值,从阈值/codeFactor,经过预热时长,才达到设置的QPS阈值
排队等待:匀速排队,让请求以匀速通过,阈值类型必须设置为QPS,否则无效
QPS直接失败
直接->快速失败 系统默认:表示1秒钟查询次数在单机阈值以内就是OK,超过就直接失败,报默认错误
默认设置的阈值类型是QPS
报错信息:Blocked by Sentinel (flow limiting)
访问频率降低后可以自动恢复。
思考:直接调用默认报错信息,技术方面OK,但是but,是否应该有我们自己的后续处理?
应该有个fallback方法,自己配置
线程数直接失败
改造controller
@RestController
public class FlowLimitController {
@GetMapping("/testA")
public String test001(){
try {
TimeUnit.MILLISECONDS.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "testA";
}
@GetMapping("/testB")
public String test002() {
return "testB";
}
}
中间犯得一次错误:注意:MICROSECONDS 和MILLSECONDS的区别 微秒和毫秒
重启后访问一次testA 和testB ,链路出现后设置流控:
设置链路流控:
设置testA 为 阈值类型:线程数,单机阈值 1
返回访问 多次点击后出现blocked by sentinel
线程数和QPS的区别:
QPS是直接拒绝,关在大门外,而线程数是放进来,但是同时只能执行阈值数,多了就不行了
关联
是什么:当关联的资源达到阈值时,就限流自己
当与A关联的资源B达到阈值后,就限流A自己
B惹事,A挂了
如何配置:在高级选项里设置 /testA和/testB的关联
设置效果:当关联资源/testB的qbs阈值达到1时,就限流/testA的Rest访问地址,当关联资源达到阈值后闲置配置好的资源名
postman模拟并发秘籍访问testB
先试着访问testB ,可以访问,点击框的最右侧的save as ,保存进folder,
第二步:点击文件夹右边三个点上方的右向箭头,出现collection信息,点击相应的请求后,点击上方的Run按钮
第三步:上面步骤点击Run后出现Collection Runner界面,可以设置请求的信息,可以设置多少次访问,间隔多长时间
run: 大批量线程高并发访问B,导致A失效了
点击访问 testA 结果发现:blocked by sentinel (flow limiting)
注意(容易错的地方):谁关联谁?谁出错?
在监控中,设置资源名 /testA 关联 /testB,也就是下方的那个
在postman中 大批量密集访问 /testB,然后去访问/testA,发现/testA失效 ,常犯错误就是设置反了
流控效果
直接
直接-> 快速失败(默认的流控处理)
直接失败,抛出异常 blocked by Sentinel(flow limiting)
源码 com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
预热
说明:公式:阈值除以coldFactor(默认是3),经过预热时长后才会达到阈值
Warm Up 方式,即预热/冷启动方式。当系统长期处于低水位情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过“冷启动”,让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给系统一个预热的时间,避免冷系统被压垮。
解释:默认 coldFactor为3,即请求 QPS 从 threshold / 3 开始,经过预热时长逐渐升到设定的QPS阈值。具体可以看官网。
案例:阈值为10 ,并且预热时长设置为5秒
系统初始化的阈值 为 10 / 3约等于3,即阈值开始为3;然后过了5秒后阈值才慢慢升高恢复到10.
具体实现可以看源码 WarmUpController
试验: 设置WarmUp , QPS,阈值为10.预热时长为5,
操作:快速点击,开始还有失败,5秒后便不再失败,因为阈值升高了。
应用场景:秒杀系统在开始的瞬间,会有很多流量,可能把系统打崩,预热可以保护系统,慢慢提高到设定的阈值。
排队等待
匀速排队,让请求以均匀的速度通过,阈值类型必须设置成QPS,否则无效。
可以设置单机阈值1 表示 每秒1次请求,超过的话就排队等待,超时时间设置为20000,表示等待的超时时间为20000毫米。
匀速排队会严格控制请求通过的间隔时间,让请求以均匀的速度通过,对应的是漏桶算法。
这种方式主要用来处理间隔性突发的流量,如消息队列。
降级规则
降级简介
官网:熔断降级: https://github.com/alibaba/Sentinel/wiki/%