SpringCloud 整合 Sentinel 实现服务自动熔断限流配置持久化存储,实战讲解!
一、背景介绍
在上一篇文章中,我们详细介绍了如何使用 Sentinel 来实现服务的限流和降级操作,同时也遗留的一个问题:如何将 Sentinel 规则数据进行持久化存储?
今天通过这篇文章,并结合之前的知识,我们一起来了解一下 Sentinel 数据持久化存储思路。
二、方案实践
在上篇文章中,我们简单介绍了 Sentinel 控制台的使用,当我们在控制台对某个客户端的资源设置相关规则时,Sentinel 会自动将这些规则推送给客户端并保存到内存中。
也就是说,当我们重启客户端的时候,这些规则也会丢失。有没有一种办法将 Sentinel 规则数据持久化存储。
答案也是肯定的,Sentinel 支持多种数据源存储,例如 ZooKeeper,Nacos,Apollo。这里我们介绍一下使用 Nacos 的配置中心来存储 Sentinel 相关的规则数据。
服务之间的交互逻辑,可以用如下图来概括。

具体实现步骤如下!
2.1、创建限流规则配置文件
首先,在 nacos 创建一个限流规则配置文件,具体示例如下。

其中DataId
值为alibaba-sentinel-client-rules
,所属Group
值为SENTINEL_GROUP
;配置格式选择JSON
,并在配置内容中填入下面的内容:
[
{
"resource": "hello",
"limitApp": "default",
"grade": 1,
"count": 5,
"strategy": 0,
"controlBehavior": 0,
"clusterMode": false
}
]
可以看到上面配置规则是一个数组类型,数组中的每个对象是针对每一个要保护资源的配置信息,每个对象中的属性作用如下:
resource
:资源名,即限流规则的作用对象limitApp
:流控针对的调用来源,若为default
则不区分调用来源grade
:限流阈值类型;0 代表根据线程数来限流,1 代表根据 QPS 来限流count
:限流阈值strategy
:调用关系限流策略controlBehavior
:流量控制效果(直接拒绝、Warm Up、匀速排队)clusterMode
:是否为集群模式
实际上还有非常多可配置选项和规则,这里为了方便演示,只做简单的配置介绍。详细的配置参数可以参考 sentinel 官网文档。
2.2、sentinel 客户端添加数据源
客户端要想使用 Nacos 中配置的限流规则数据,此时需要对应用进行一些改造,具体实现步骤如下。
首先,在应用引入nacos
相关依赖,示例如下:
<dependencies>
<!-- SpringBoot web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 服务限流和熔断处理:sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--以nacos作为sentinel数据源的依赖-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
</dependencies>
这里的sentinel-datasource-nacos
不需要填写版本号,因为在spring-cloud-starter-alibaba-sentinel
已经配置了。
然后,在application.properties
文件中配置nacos
数据源,示例如下:
spring.application.name=alibaba-sentinel-client
server.port=8002
# sentinel dashboard
spring.cloud.sentinel.transport.dashboard=localhost:8080
# 配置sentinel数据源
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds2.nacos.data-id=alibaba-sentinel-client-rules
spring.cloud.sentinel.datasource.ds2.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=flow
2.3、服务测试
最后启动服务,再次访问 Sentinel 控制台,点击流控规则-》回到单机页面
,可以看到刚刚创建的限流规则信息。

实际上,Sentinel Dashboard 会收集客户端中定义的数据源,然后向目标数据源拉取相关的限流规则信息,因此可以看到在 Nacos 中配置的数据。
将 Nacos 中的限流规则阀值改成1
,看看是否能实时同步到 Sentinel 控制台。

再次刷新流控规则
页面,可以看到如下信息,限流规则阀值改成1
。

最后再次访问客户端的http://127.0.0.1:8002/hello
接口,限流效果非常明显。

三、反向修改同步到 Nacos
看完以上的案例之后,可能有的同学又会发出疑问,自己在 Sentinel Dashboard 中修改了限流规则,但是没有同步到 Nacos 配置中心,当客户端服务重启之后,还是原来的配置规则,请问怎么实现 Sentinel Dashboard 与 Nacos 的双向数据同步?
很遗憾的告诉大家,目前 Sentinel Dashboard 并没有直接将数据同步到 Nacos 的配置,要想实现这个功能得自己修改源代码,然后重新编译打包部署。
实现过程有些复杂,在此我以流控规则
的数据同步为例,向大家介绍其改造的过程,其他的规则改造逻辑也类似。
3.1、下载源码
首先,访问 Sentinel 官网仓库地址,将源代码下载来了,然后导入到 IDEA 中。
然后,切换到与应用匹配的版本号,例如本案例中使用的 Sentinel 的版本号是1.7.2
,使用 IDEA 自带的 git 工具切换到目标分支。

接着,打开sentinel-dashboard
模块中的pom.xml
,将sentinel-datasource-nacos
的scope
标签注释掉。

3.2、修改流控规则源码
3.2.1、创建数据查询和同步服务
首先,打开test
文件夹下的com.alibaba.csp.sentinel.dashboard.rule.nacos
包,找到如下四个文件。

将nacos
包下的四个文件,拷贝到main
文件夹下的com.alibaba.csp.sentinel.dashboard.rule
包中。

然后,打开NacosConfigUtil
类,其中有两个重要的参数需要特别注意,在 Nacos 中创建配置时会用到。

GROUP_ID
:代表配置文件所属分组,对应 Nacos 中配置规则所属的Group
FLOW_DATA_ID_POSTFIX
:代表流控规则配置后缀名称,例如客户端的应用名称为alibaba-sentinel-client
,那么 Sentinel Dashboard 生成的配置规则文件名为alibaba-sentinel-client-flow-rules
,对应 Nacos 中配置规则所属的DataId
最后,打开NacosConfig
,填写 Nacos 配置中心相关的地址信息,以便与 Nacos 进行数据同步。

3.2.2、修改流控规则接口
打开controller
文件夹,找到FlowControllerV2
,它是一个流控规则备用接口类,将上文中FlowRuleNacosProvider
和FlowRuleNacosPublisher
类注入到FlowControllerV2
中,并替换到原来的接口。

// 修改前的代码
@Autowired
@Qualifier("flowRuleDefaultProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleDefaultPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;
// 修改后的代码
@Autowired
private FlowRuleNacosProvider ruleProvider;
@Autowired
private FlowRuleNacosPublisher rulePublisher;
3.2.3、修改流控规则页面
在webapp
文件夹下,找到sidebar.html
文件,它是一个左侧菜单页面,找到流控规则
按钮代码,将dashboard.flowV1
修改成dashboard.flow
。

<!--修改前的代码-->
<li ui-sref-active="active">
<a ui-sref="dashboard.flowV1({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则
</a>
</li>
<!--修改后的代码-->
<li ui-sref-active="active">
<a ui-sref="dashboard.flow({app: entry.app})">
<i class="glyphicon glyphicon-filter"></i> 流控规则
</a>
</li>
按住ctrl
并点击dashboard.flow
,可以跳转到对应的 JS 详情页面。


可以清晰的看到dashboard.flow
对应的Controller
接口类为FlowControllerV2
,当我们在控制台修改流控规则时,就会利用上文的 Nacos 服务类自动同步到 Nacos 配置中心。
3.2.4、重新打包部署服务
最后将sentinel-dashboard
工程执行打包编译操作。
mvn clean package
获取最新的sentinel-dashboard.jar
,然后按照上文介绍的方式重新部署服务。
如果是本地调试,也可以直接通过 IDEA 启动 Sentinel Dashboard 服务。
3.3、在 Nacos 创建配置文件
首先 Sentinel Dashboard 是无法自动在 Nacos 中帮我们创建配置规则文件的,因此需要我们手工创建配置规则。
根据上文的配置信息,我们可以在 Nacos 中创建一个DataId
为alibaba-sentinel-client-flow-rules
,Group
为SENTINEL_GROUP
的限流配置规则,具体内容如下:

3.4、客户端添加数据源
重新打开alibaba-sentinel-client
工程,根据最新的限流配置规则文件,重新配置 sentinel 数据源,示例如下:
spring.application.name=alibaba-sentinel-client
server.port=8002
# sentinel dashboard
spring.cloud.sentinel.transport.dashboard=localhost:8080
# 配置sentinel数据源
spring.cloud.sentinel.datasource.ds2.nacos.server-addr=127.0.0.1:8848
spring.cloud.sentinel.datasource.ds2.nacos.data-id=alibaba-sentinel-client-flow-rules
spring.cloud.sentinel.datasource.ds2.nacos.group-id=SENTINEL_GROUP
spring.cloud.sentinel.datasource.ds2.nacos.data-type=json
spring.cloud.sentinel.datasource.ds2.nacos.rule-type=flow
然后将alibaba-sentinel-client
服务进行重启。
3.5、服务测试
再次访问 Sentinel 控制台,点击流控规则
,可以看到从 Nacos 配置中心获取的最新限流规则数据。

点击编辑
,将当前限流规则的阀值修改成5
并保存。

回到 Nacos 配置中心控制台,点击alibaba-sentinel-client-flow-rules
配置,可以看到详情中的限流规则阀值被改成最新值。

到这里,Sentinel Dashboard 和 Nacos 之间的数据双向同步就完成了,当在 Sentinel Dashboard 中新增流控规则的时候也会同步到 Nacos 中,大家也可以自信尝试。
其它的规则改造过程也基本类似,先改服务接口,再改前端页面逻辑,确保 Nacos 中的配置名称与 Sentinel Dashboard 生成的配置规则名称一致,基本上就没什么问题了。
四、小结
最后总结一下,在实际的开发过程中,我们可以利用 Nacos 的配置中心功能,集中存储 Sentinel 各种规则数据,依次来实现数据的持久化存储。目前 Sentinel 控制台并没有直接支持将修改后的数据同步到 Nacos 的配置,因此需要修改源代码进行重新编译打包部署。
本文内容比较多,如果有描述不对的地方,欢迎大家在评论区留言指出!
五、参考
1、https://sca.aliyun.com/docs/2.2.x/user-guide/sentinel/overview
2、https://developer.aliyun.com/article/783342
3、https://sentinelguard.io/zh-cn/docs/introduction.html
作者:潘志的技术笔记
出处:https://pzblog.cn/
版权归作者所有,转载请注明出处
