前言

之前老顾介绍了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 配置自动刷新demo nacos动态更新_nacos 配置自动刷新demo


本人介绍和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哦

配置


nacos 配置自动刷新demo nacos动态更新_推送_02


  • 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 配置自动刷新demo nacos动态更新_推送_03


Nacos中创建限流规则的配置

在Nacos控制台,对应的namespace ,新建一个json配置文件:DataID为scb-content-service-flow-rules,Group为SENTINEL_GROUP;如下


nacos 配置自动刷新demo nacos动态更新_nacos动态更新数据源_04


为什么DataId的后缀为flow-rules,这个和下面的Sentinel控制台相结合的时候决定的。

配置内容json格式化一下


nacos 配置自动刷新demo nacos动态更新_推送_05


配置内容:是不是看上去很多信息,也不知道是什么含义。上面的信息是全部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:是否为集群模式


nacos 配置自动刷新demo nacos动态更新_推送_06


启动scb-content-service应用,注册到nacos到,打开Sentinel控制台,可以看到上面nacos新建的限流规则,如下:


nacos 配置自动刷新demo nacos动态更新_限流_07


注意:

在完成了上面的整合之后,对于接口流控规则的修改就存在两个地方了: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版本


nacos 配置自动刷新demo nacos动态更新_spring_08


修改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 配置自动刷新demo nacos动态更新_nacos 配置自动刷新demo_09


即初始化nacos的ConfigService对象,这里需要配置好serverAddr、namespace、以及nacos的用户名和密码。

对应的DashboardConfig也需要改造,增加配置项


nacos 配置自动刷新demo nacos动态更新_推送_10


nacos 配置自动刷新demo nacos动态更新_spring_11


启动的时候,需要再jvm参数中加上对应的配置项


nacos 配置自动刷新demo nacos动态更新_nacos 配置自动刷新demo_12


增加NacosProvider和NacosPublisher

添加多个规则的的拉取、推送实现类


nacos 配置自动刷新demo nacos动态更新_限流_13


流控规则拉取和推送


nacos 配置自动刷新demo nacos动态更新_nacos 配置自动刷新demo_14


nacos 配置自动刷新demo nacos动态更新_限流_15


其中原理就是,拉取从nacos的配置文件读取;在Sentinel控制台设置流控规则时,就把信息推送到nacos服务中

其他的规则,很类似,代码差不多;唯一区别就是 Entity,如下


nacos 配置自动刷新demo nacos动态更新_spring_16


nacos 配置自动刷新demo nacos动态更新_推送_17


老顾就不罗列 其他的规则了。

我们再看看NacosConfigUtil


nacos 配置自动刷新demo nacos动态更新_spring_18


这个就是不同规则的DataId的后缀,如:flow就是以flow-rules为后缀

现在明白为什么上面定义的DataId会有后缀了吧

改造Controller

修改流控规则 FlowControllerV1

添加我们flow的 Publisher 和 Provider


nacos 配置自动刷新demo nacos动态更新_推送_19


新增推送到nacos的方法


nacos 配置自动刷新demo nacos动态更新_nacos动态更新数据源_20


将原来的读取方法中的 List rules = sentinelApiClient.fetchFlowRuleOfMachine(app, ip, port);

改为List rules = ruleProvider.getRules(app);


nacos 配置自动刷新demo nacos动态更新_推送_21


将原来设置更新方法中的publishRules(entity.getApp(), entity.getIp(), entity.getPort()).get(5000, TimeUnit.MILLISECONDS);改为publishRules(entity.getApp());


nacos 配置自动刷新demo nacos动态更新_nacos动态更新数据源_22


其他规则的controller是一样的改造。


nacos 配置自动刷新demo nacos动态更新_限流_23


修复源码bug

在降级规则设置时,Sentinel控制台界面缺失了统计时长的设置,如果不设置,默认是1秒;这个就不是太友好了。我们需要把统计时长放到界面上设置


nacos 配置自动刷新demo nacos动态更新_nacos动态更新数据源_24


修改降级界面,在此界面中增加统计时长的属性


统计时长

ms


改造完后,界面如下


nacos 配置自动刷新demo nacos动态更新_nacos动态更新数据源_25


微服务工程改造

增加 sentinel与nacos整合后的依赖后,还需要加上

com.alibaba.csp   sentinel-datasource-nacos

配置文件中加入


nacos 配置自动刷新demo nacos动态更新_nacos 配置自动刷新demo_26


nacos 配置自动刷新demo nacos动态更新_spring_27


这样到此为止就改造好了

这样无论是重启 nacos也好,sentinel也罢,业务工程也罢,都不会丢失sentinel信息。而且可以很好的用Sentinel控制台进行设置,是不是很酷啊