sentinel动态规则
前言
我们在Sentinel Dashboard中配置流控规则(限流策略)、熔断规则(熔断策略)、热点规则(热点数据限流规则)。这些规则是存储在内存中的,一旦被监控项目重启配置的规则会被清掉(可以修改为nacos、数据库等)。基于这种情况sentinel支持我们使用nacos、zk等组件配置规则。此处以nacos配置动态规则为例介绍一下
sentinel动态规则
nacos配置动态规则
引入依赖
xml
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.9</version>
</dependency>
修改yml文件配置sentinel去读nacos配置
yaml
spring:
cloud:
sentinel:
datasource:
flow: # ✅ :流控规则(QPS/并发线程数限流)最常用
#degrade: # ✅ 熔断降级规则(异常比例/慢调用/异常数熔断)重点必配
#param-flow: # ✅ 热点参数限流规则(对接口参数限流,比如你的userId)重点必配
#authority: # 黑白名单规则(按调用来源限流)
#system: # 系统保护规则(全服务入口限流,保护服务器CPU/负载)
#gateway-flow: # 网关限流规则(只有SpringCloud Gateway网关服务才需要,你的业务服务不用配)
nacos:
server-addr: 127.0.0.1:8848
# 若Nacos开启鉴权,添加账号密码
username: nacos
password: nacos
dataId: system-flow-rules
groupId: DEFAULT_GROUP
#sentinel 相关配置
rule-type: flow # rule-type要和datasource下的配置保持一致
data-type: json #配置规则是json格式 数组类型
nacos上添加规则

通过上述配置后,我们可以在nacos上新增、修改配置,配置会自动生效。
控制台变更规则推送方案
nacos配置动态规则后,但是只能在nacos上修改、新增规则,在控制台修改nacos的修改新增,不会同步到nacos配置上,所以需要做一些调整来支持控制台修改规则同步nacos。推荐有两种方式
| 方案 | 是否推荐 | 说明 |
|---|---|---|
| 1. 控制台当临时工具 | ❌ | 重启即丢 |
| 2. 只用 Nacos,不用控制台改规则 | ✅ | 最稳妥 |
| 3. 二次开发 Sentinel Dashboard | ⭐⭐⭐⭐ | 最主流 |
| 4. 自己写规则管理后台 | ⭐⭐⭐ | 架构型方案 |
| 5. 推模式(Push)改造 | ⭐⭐ | 成本高 |
| 模式 | 介绍 |
|---|---|
| 原始模式(Embedded) | 规则硬编码至应用,存储于内存,无持久化, 变更需修改代码并重启应用,仅适用于本地测试、功能验证场景 |
| Pull 拉模式 | 客户端主动定时轮询数据源(本地文件 / 数据库), 规则持久化存储,变更后需等待轮询间隔生效, 适合单机、轻量且对规则生效时效要求不高的场景 |
| Push 推模式 | 规则存储于远程配置中心(Nacos/Apollo 等) 客户端与配置中心建立长连接并监听规则变更 服务端主动推送新规则至客户端 实时生效且集群规则强一致,是生产环境集群部署的首选方案 |
生产推荐使用push 推模式

1、sentinel控制台变更 保存并推送到nacos、zk等
2、服务通过nacos、zk等数据源动态获取到规则。
控制台变更规则推送实操
官网推荐使用改在Sentinel Dashboard源码方式支持,控制台修改规则同步到nacos中,改造步骤如下
其实sentinel 1.8及以上其在测试模块中已经帮我实现了相关nacos同步的demo,其引入了相关依赖(test作用域)、FlowRuleNacosProvider 和FlowRuleNacosProvider类,可以参考该逻辑进行处理
下载源码
sentinel源码路径 关注sentinel-dashboard模块
引入nacos依赖
xml
<!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<!-- 注释掉 -->
<!--<scope>test</scope>-->
</dependency>
添加配置
yaml
#nacos 配置
nacos.server-addr=127.0.0.1:8848
nacos.namespace=sentinel #不填写默认是public空间下
nacos.username=nacos
nacos.password=nacos
实现nacos规则发布和读取器

| 类名 | 作用与核心职责 |
|---|---|
FlowRuleNacosPublisher(核心类) |
规则发布器,负责将控制台变更的流控规则推送到 Nacos 进行持久化 |
FlowRuleNacosProvider(核心类) |
规则读取器,负责从 Nacos 读取流控规则并加载到控制台 |
NacosConfig |
Nacos 核心配置类 ,用于初始化 Nacos 客户端连接 (默认链接localhost,如果nacos不在本地,则需要改造) |
NacosConfigUtil |
常量工具类,定义 Nacos 配置的统一常量 |
参考test目录下的nacos相关类 编写(复制-完善)到java目录中rule/nacos中(没有目录新建)。
FlowRuleNacosProvider实现从nacos读取流控规则
java
@Component("flowRuleNacosProvider")
public class FlowRuleNacosProvider implements DynamicRuleProvider<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<String, List<FlowRuleEntity>> converter;
@Override
public List<FlowRuleEntity> getRules(String appName) throws Exception {
//从在application.properties配置的命名空间,dataId=app+"-flow-rules",
//group ="SENTINEL_GROUP" 下读取流控规则
String rules = configService.getConfig(appName + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, 3000);
if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);
}
}
FlowRuleNacosPublisher向nacos推送规则
java
@Component("flowRuleNacosPublisher")
public class FlowRuleNacosPublisher implements DynamicRulePublisher<List<FlowRuleEntity>> {
@Autowired
private ConfigService configService;
@Autowired
private Converter<List<FlowRuleEntity>, String> converter;
@Override
public void publish(String app, List<FlowRuleEntity> rules) throws Exception {
AssertUtil.notEmpty(app, "app name cannot be empty");
if (rules == null) {
return;
}
//推送到我们在application.properties配置的命名空间下,dataId=app+"-flow-rules",
//group ="SENTINEL_GROUP" 下
configService.publishConfig(app + NacosConfigUtil.FLOW_DATA_ID_POSTFIX,
NacosConfigUtil.GROUP_ID, converter.convert(rules));
}
}
改造v2类型接口
其实在sentinel Dashboard中的客户端集群模式下是支持v2接口的进行规则发布器和读取的。替换类下com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2.java 中的Publisher/Provider依赖实现 使用我们Nacos实现

依赖默认是flowRuleDefaultProvider 、flowRuleDefaultPublisher(基于内存读取、通知) 改成flowRuleNacosProvider、flowRuleNacosPublisher(基于nacos读取、通知) ,改造好了后v2相关接口对于流控规则的新增,变更操作都会同步到nacos。
注意
**控制台只有在集群模式下才会走v2的相关接口(v2相关接口)=需要手动使用v2/flow 形式显示指定url来控制。如下:http://127.0.0.1:8081/#/dashboard/v2/flow/ruoyi-system。此处可以改造流控规则的前端页面指向,将原来的v1改成v2接口。

改造后sentinel-dashboard-nacos 代码
支持使用jar启动 传入nacos,命令如下:
java \
-Dsentinel.nacos.serverAddr=生产Nacos地址:8848 \
-Dsentinel.nacos.username=生产账号 \
-Dsentinel.nacos.password=生产密码 \
-Dsentinel.nacos.namespace=生产命名空间ID \
-jar 你的项目.jar
默认会使用生产命名空间ID下的dataId={appName}-flow-rules的group=SENTINEL_GROUP文件下变更流控规则
改造控制单机模式接口
因为控制台默认是单机页面
参考v2接口,其在所有规则数据发生变化情况下,重新重内存规则中获取所有规则,发布到具体数据源(nacos、zk、内存等)
java
private void publishRules(/*@NonNull*/ String app) throws Exception {
//查找所有流控规则
List<FlowRuleEntity> rules = repository.findAllByApp(app);
//数据发布(同步都具体实现 对接nacos就同步到nacos)
rulePublisher.publish(app, rules);
}
可以仿照类似v2接口 在其所有流控规则的增删改修改后,都给其调用publishRules方法触发规则同步到v1
重新修改服务从nacos获取规则的配置
注意需要保证sentinel控制台推送规则到nacos的对应namespace、dataId、groupId 等都保持一致。
spring:
cloud:
sentinel:
datasource:
ds1:
nacos:
server-addr: 127.0.0.1:8848
# 必须与控制台推送的namespace完全一致(默认是public)
namespace: sentinel
# 必须与控制台推送的dataId完全一致
dataId: ${spring.application.name}-flow-flues
# 必须与控制台推送的groupId完全一致
groupId: SENTINEL_GROUP
data-type: json
rule-type: flow