SpringCloud Alibaba Sentinel---实现熔断与限流
前言:不断学习就是程序员的宿命
一、概述
Github官网:https://github.com/alibaba/Sentinel,就是SpringCloud的Hystrix
下载地址:https://github.com/alibaba/Sentinel/releases
二、Sentinel 控制台
1、启动Sentinel
java -jar sentinel-dashboard-1.7.0.jar
2、登录Web界面
浏览器访问:http://localhost:8080/,用户名密码均为:sentinel
三、Sentinel流控规则
1、流控模式
1.1直接 (默认)
1.1.1 QPS直接失败
以下设置表示:1秒钟内查询1次就是OK,若次数超过1,就直接-快速失败,报默认错误
1.1.2线程数直接失败
1.2、关联
当关联的资源达到阈值时,就限流自己;当与A关联的资源B达到阈值时,就限流A自己(B惹事,A挂了)
设置:当关联资源/testB的qps阈值超过1时,就限流/testA的Rest访问地址,当关联资源达到阈值后限制配置好的资源名。
2、流控效果
Github:https://github.com/alibaba/Sentinel/wiki/Flow-Control
2.1 直接-快速失败
直接失败,抛出异常:Blocked by Sentinel(flow limiting)
源码:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
2.2 直接-预热
默认coldFactor为3,即请求QPS从threshold/3开始,经预热时长逐渐升至设定的QPS阈值。限流冷启动
以下是指开始QPS为10/3=3,5秒后慢慢预热至10
2.3排队等待
匀速排队,阈值必须设置为QPS(漏桶算法)
源码:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController
以下设置含义:/testA每秒1次请求,超过的话就排队等待,等待的超时时间为20000毫秒。
四、Sentinel降级规则
Github:https://github.com/alibaba/Sentinel/wiki/%E7%86%94%E6%96%AD%E9%99%8D%E7%BA%A7
Sentinel断路器没有半开状态(Hystrix断路器是存在半开状态的)
1、RT
以下表示:Jmeter永远1秒钟打进来10个线程(大于5,官网)调用testD,我们希望200毫米处理完本次任务。如果超过200毫秒还没处理完,在未来1秒钟的时间窗口内,断路器打开(保险丝跳闸)微服务不可用,保险丝跳闸断电。
2、异常比例
按照以下配置:
①单独访问一次,必然来一次报错一次(int a =10/0;)
②开启Jmeter,直接高并发发送请求,多次调用达到官网配置条件,断路器开启(保险丝跳闸)微服务不可用,不在报错error而是服务降级了。
3、异常数
异常数是按照分钟统计的,访问:http://localhost:8401/testExceptionCount,第一次访问绝对报错(int a = 10/0);但是达到配置的阈值(5)次报错后,进入熔断后降级。
五、热点规则
官网:https://github.com/alibaba/Sentinel/wiki/%E7%83%AD%E7%82%B9%E5%8F%82%E6%95%B0%E9%99%90%E6%B5%81
1、热点key限流
配置第一个参数(索引0)阈值为1,违背则会进入Fallback兜底方法
2、参数例外项
基于上述热点规则,期望p1参数当它为某个特殊值时,限流值与平时不太一样(例如当p1=5时,它的阈值为200)
六、系统规则
从整体维度对应用入口流量进行控制,而之前限流是细粒度对某个方法进行QPS等配置,这个是整体级别的。
七、SentinelResource配置
Github:https://github.com/alibaba/Sentinel/wiki/%E6%B3%A8%E8%A7%A3%E6%94%AF%E6%8C%81
1、按资源名限流
关闭8401服务,查看流控规则消失,发现规则是临时的
2、按URL地址限流
3、自定义限流处理逻辑
上述问题:
①系统默认的,没有体现我们自己的业务要求
②依照现有条件,我们自定义的处理方法又和业务代码耦合在一起,不直观
③每个业务方法都添加一个兜底方法,那代码膨胀
④全局统一的处理方法没有体现
(1)新增自定义处理方法
public class CustomerBlockHandler { public static CommonResult handlerException(BlockException exception) { return new CommonResult(444, "客户自定义,global handlerException---1"); } public static CommonResult handlerException2(BlockException exception) { return new CommonResult(444, "客户自定义,global handlerException---2"); } }
(2)引用
八、Sentinel服务熔断Ribbon
1、无配置
测试情况:
2、配置Fallback,只负责业务异常
测试情况:
3、配置blockhandler,只负责Sentinel控制台配置违规
测试情况:
4、配置Fallback和blockhandler
测试情况:
5、异常忽略-exceptionsToIgnore
测试情况:
九、Sentinel服务熔断OpenFeign
1、application.yml开启对feign支持
#激活sentinel对feign的支持 feign: sentinel: enabled: true
2、主类启用注解@EnableFeignClients
3、Feign接口
测试情况:停掉9003提供者,服务降级了
十、熔断框架比较
十一、Sentinel规则持久化
之前配置在Sentinel的规则在微服务重启,规则丢失。
思路:将限流规则持久化进Nacos保存,只要刷新微服务的某个Rest地址,Sentinel控制台的流控规则就能看到,只要Nacos里面的配置不删除,针对某个微服务的Sentinel规则持续有效
1、application.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,如果被占用会自动+1,直到找到为止 port: 8719 # 流控规则持久化到nacos datasource: dsl: nacos: server-addr: localhost:8848 data-id: ${spring.application.name} group-id: DEFAULT_GROUP data-type: json rule-type: flow management: endpoints: web: exposure: include: "*"
2、Nacos控制台新建配置文件
DataId为spring.application.name,json格式如下:
[ { "resource":"/rateLimit/byUrl", "limitApp":"default", "grade":1, "count":1, "strategy":0, "controlBehavior":0, "clusterMode":false } ]
①resource:资源名称(默认请求路径)
②limitApp:来源应用默认
③grade:阈值类型,0表示线程数,1表示QPS
④count:单机阈值
⑤strategy:流控模式,0表示直接,1表示关联,2表示链路
⑥controlBehavior:流控效果:0表示快速失败,1表示warmup,2表示排队等待
⑦clusterMode:是否集群