10、Sentinel 控制台源码改造实现流控规则持久化

之前遗留问题

之前我们集成了Nacos,实现了推送规则到客户端,但是控制台添加的规则不能持久化到Naocs中,这时需要对控制台源码进行改造。

先来回顾下默认添加流控规则的执行流程:

 

1、 控制台添加规则,会同步到sentinel服务端的内存中;
2、 然后调用客户端API,远程请求添加规则接口,同步到客户端内存中;

查询规则时流程如下:

 

1、 控制台调用远程API,查询客户端内存中的规则;
2、 将客户端查询到的规则,重新存放到sentinel服务端内存中,会事先清理;

官网提供的解决方案

方案流程

生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源,如远程配置中心(ZooKeeper, Nacos, Apollo等等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送,数据源仅负责获取配置中心推送的配置并更新到本地。

因此推送规则正确做法应该是:配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel客户端数据源 → Sentinel客户端。

 

自己画图,更容易理解,首先控制台调用Nacos,实现规则添加、删除、修改等,然后Nacos推送规则到客户端。查询规则时,则直接调用Nacos中的API查询。这样就实现了控制台和Nacos规则的双向同步。

 

方案细节

从Sentinel 1.4.0 开始,Sentinel 控制台提供 DynamicRulePublisher 和 DynamicRuleProvider 接口用于实现应用维度的规则推送和拉取,并提供了相关的示例。

  • DynamicRuleProvider: 拉取规则
  • DynamicRulePublisher: 推送规则

提供了Nacos、ZooKeeper 和 Apollo 的推送和拉取规则实现示例(位于 test 目录下)。

 

Sentinel 提供流控规则推送的示例页面(/v2/flow),用户改造控制台对接配置中心后可直接通过 v2 页面推送规则至配置中心。

 

以Nacos 为例,若希望使用 Nacos 作为动态规则配置中心,用户可以提取出相关的类,然后只需在 FlowControllerV2 中指定对应的 bean 即可开启 Nacos 适配。前端页面需要手动切换,或者修改前端路由配置(sidebar.html 流控规则路由从 dashboard.flowV1 改成 dashboard.flow 即可,注意簇点链路页面对话框需要自行改造)。

@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;

修改控制台源码实现流控规则持久化

接下来,参考以上官方提供的解决方案,我们来实际操作一下

1. 改造代码

首先将pom中的sentinel-datasource-nacos中的scope去掉,将Nacos相关依赖引入到编译环境中来。

 

将test目录下nacos动态规则实现的相关代码,复制到com.alibaba.csp.sentinel.dashboard.rule包下。

 

修改FlowControllerV2类,将动态规则发布及拉取的注入类,替换为flowRuleNacosProvider及flowRuleNacosPublisher。

 

2. 改造页面

找到图中目录下的sidebar页面,将流控规则菜单中的dashboard.flowV1改为dashboard.flow。

 

可以看到flow调用的页面和接口是V2相关的内容。

 

案例测试

1. 添加规则

重启修改源码后的控制台,刷新页面,可以看到页面菜单已经被修改了。

在新菜单中添加规则并保存。

 

在Nacos配置管理中,搜索SENTINEL_GROUP分组的配置文件,发现了一个自动生成的配置。

 

我们控制台添加的配置就被持久化到了Nacos中。

 

默认自动生成的Nacos配置适配的 dataId 和 groupId 约定如下:

  • groupId: SENTINEL_GROUP
  • 流控规则 dataId: {appName}-flow-rules,比如应用名为 appA,则 dataId 为 appA-flow-rules

用户可以在 NacosConfigUtil 修改对应的 groupId 和 dataId 前缀。

用户可以在 NacosConfig 配置对应的 Converter,默认已提供 FlowRuleEntity 的 decoder 和 encoder。

此时需要在客户端中修改groupId 和dataId 。将Nacos中新增的规则Push过来。注意rule-type:如果是网关流控规则数据源类型是 gw-flow,若将网关流控规则数据源指定为 flow 则不生效。

 

访问接口,发现限流成功,规则生效。
 

遗留问题

上面我们分析了控制台实现持久化页面规则,发现sentinel远程已经提供了方案,其他规则,都需要参照流控规则的方式进行改造。。。还是比较麻烦的。