前言
之前老顾介绍了Sentinel相关的业务介绍,小伙伴们用的怎么样呢?今天老顾来介绍另一个话题,就是Sentinel一旦重启,配置规则就会消失。那肯定是不能够用在生产环境的,我们需要把规则持久化,老顾来介绍一下nacos里面。顺便解决一个DashBoard的源码一个bug
动态限流规则
Sentinel 动态规则扩展
Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:
- 通过 API 直接修改 (loadRules)
- 通过 DataSource 适配不同数据源修改
通过API编码的方式
FlowRuleManager.loadRules(List rules); //修改流控规则DegradeRuleManager.loadRules(List rules); // 修改降级规
编码的方式一般仅用于测试和演示,生产上一般通过动态规则源的方式来动态管理规则
规则管理和推送
官网介绍,规则推送有三种模式:
1)原生模式:API 将规则推送至客户端并直接更新到内存中;规则保存在内存中,重启即消失。严重不建议用于生产环境
2)pull模式:即拉模式,客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等;实时性不保证,拉取过于频繁也可能会有性能问题。
3)push模式:即推模式,规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源
Push模式与DataSource 扩展
生产环境下一般更常用的是push模式的数据源。对于push模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是 配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel,而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了:
本人介绍和nacos相结合的方式
Nacos
准备环境
因为同时使用到Nacos和Sentinel Dashboard,所以可以先把Nacos和Sentinel Dashboard启动起来。
默认配置下启动后,它们的访问地址为:
- Nacos:http://localhost:8848/
- Sentinel Dashboard:http://localhost:8081/
POM依赖
在某个微服务下,引入依赖Spring Cloud Alibaba的Sentinel模块和Nacos存储扩展
com.alibaba.cloud spring-cloud-starter-alibaba-sentinelcom.alibaba.csp sentinel-datasource-nacoscom.alibaba.cloud spring-cloud-starter-alibaba-nacos-configcom.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery
不要忘了 引用sentinel-datasource-nacos哦
配置
- spring.cloud.sentinel.transport.dashboard:sentinel dashboard的访问地址
- spring.cloud.sentinel.datasource.ds1-flow.nacos.server-addr:nacos的访问地址
- spring.cloud.sentinel.datasource.ds1-flow.nacos.groupId:nacos中存储规则的groupId
- spring.cloud.sentinel.datasource.ds1-flow.nacos.dataId:nacos中存储规则的dataId
- spring.cloud.sentinel.datasource.ds1-flow.nacos.rule-type:该参数是spring cloud alibaba升级到0.2.2之后增加的配置,用来定义存储的规则类型。所有的规则类型可查看枚举类:org.springframework.cloud.alibaba.sentinel.datasource.RuleType,每种规则的定义格式可以通过各枚举值中定义的规则对象来查看,比如限流规则可查看:com.alibaba.csp.sentinel.slots.block.flow.FlowRule。
Nacos中创建限流规则的配置
在Nacos控制台,对应的namespace ,新建一个json配置文件:DataID为scb-content-service-flow-rules,Group为SENTINEL_GROUP;如下
为什么DataId的后缀为flow-rules,这个和下面的Sentinel控制台相结合的时候决定的。
配置内容json格式化一下
配置内容:是不是看上去很多信息,也不知道是什么含义。上面的信息是全部flow流控的配置信息。小伙伴可以看一个简洁版的
[ { "resource": "/test", "limitApp": "default",
"grade": 1, "count": 10, "strategy": 0, "controlBehavior": 0, "clusterMode": false }]
可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个保护资源的配置对象,每个对象中的属性解释如下:
- resource:资源名,即限流规则的作用对象
- limitApp:流控针对的调用来源,若为 default 则不区分调用来源
- grade:限流阈值类型(QPS 或并发线程数);0代表根据并发数量来限流,1代表根据QPS来进行流量控制
- count:限流阈值
- strategy:调用关系限流策略
- controlBehavior:流量控制效果(直接拒绝、Warm Up、匀速排队)
- clusterMode:是否为集群模式
启动scb-content-service应用,注册到nacos到,打开Sentinel控制台,可以看到上面nacos新建的限流规则,如下:
注意:
在完成了上面的整合之后,对于接口流控规则的修改就存在两个地方了:Sentinel控制台、Nacos控制台。
这个时候,通过Nacos修改该条规则是可以同步到Sentinel的,但是通过Sentinel控制台修改或新增却不可以同步到Nacos。因为当前版本的Sentinel控制台不具备同步修改Nacos配置的能力。
而Nacos由于可以通过在客户端中使用Listener来实现自动更新。所以,在整合了Nacos做规则存储之后,需要知道在下面两个地方修改存在不同的效果:
Sentinel控制台中修改规则:仅存在于服务的内存中,不会修改Nacos中的配置值,重启后恢复原来的值。
Nacos控制台中修改规则:服务的内存中规则会更新,Nacos中持久化规则也会更新,重启后依然保持。
下面我们通过对Sentinel Dashboard的改造,使得Nacos与Sentinel可以互相同步限流规则。
Nacos与Sentinel互相同步限流规则
1、控制台推送规则
Sentinel控制台推送规则
- 将规则推送到Nacos或其他远程配置中心
- Sentinel客户端链接Nacos,获取规则配置;并监听Nacos配置变化,如发生变化,就更新本地缓存。
控制台监听Nacos配置变化,如发生变化就更新本地缓存。从而让控制台本地缓存总是和Nacos一致。
2、改造sentinel-dashboard
git官网下载Sentinel 源代码1.8版本
修改sentinel-dashboard 控制台模块的pom.xml,将test注释掉
com.alibaba.csp sentinel-datasource-nacos
修改nacos相关java代码
找到如下目录(位于test目录)
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
将整个目录拷贝到
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/nacos
即把NacosConfig和NacosConfigUtil移植过来;NacosConfig类再做些改造,增加
即初始化nacos的ConfigService对象,这里需要配置好serverAddr、namespace、以及nacos的用户名和密码。
对应的DashboardConfig也需要改造,增加配置项
启动的时候,需要再jvm参数中加上对应的配置项
增加NacosProvider和NacosPublisher
添加多个规则的的拉取、推送实现类
流控规则拉取和推送
其中原理就是,拉取从nacos的配置文件读取;在Sentinel控制台设置流控规则时,就把信息推送到nacos服务中。
其他的规则,很类似,代码差不多;唯一区别就是 Entity,如下
老顾就不罗列 其他的规则了。
我们再看看NacosConfigUtil
这个就是不同规则的DataId的后缀,如:flow就是以flow-rules为后缀
现在明白为什么上面定义的DataId会有后缀了吧
改造Controller
修改流控规则 FlowControllerV1
添加我们flow的 Publisher 和 Provider
新增推送到nacos的方法
将原来的读取方法中的 List rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);
改为List rules = ruleProvider.getRules(app);
将原来设置更新方法中的publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS);改为publishRules(entity.getApp());
其他规则的controller是一样的改造。
修复源码bug
在降级规则设置时,Sentinel控制台界面缺失了统计时长的设置,如果不设置,默认是1秒;这个就不是太友好了。我们需要把统计时长放到界面上设置
修改降级界面,在此界面中增加统计时长的属性
统计时长
ms
改造完后,界面如下
微服务工程改造
增加 sentinel与nacos整合后的依赖后,还需要加上
com.alibaba.csp sentinel-datasource-nacos
配置文件中加入
这样到此为止就改造好了
这样无论是重启 nacos也好,sentinel也罢,业务工程也罢,都不会丢失sentinel信息。而且可以很好的用Sentinel控制台进行设置,是不是很酷啊