2026/9/4 9:02:54

Sentinel 规则管理与推送模式详解

Sentinel 规则管理与推送模式详解 规则管理及推送一般来说规则的推送有下面三种模式:推送模式说明优点缺点原始模式API 将规则推送至客户端并直接更新到内存中扩展写数据源WritableDataSource简单无任何依赖不保证一致性规则保存在内存中重启即消失。严重不建议用于生产环境Pull 模式扩展写数据源WritableDataSource客户端主动向某个规则管理中心定期轮询拉取规则这个规则中心可以是 RDBMS、文件等简单无任何依赖规则持久化不保证一致性实时性不保证拉取过于频繁也可能会有性能问题。Push 模式扩展读数据源ReadableDataSource规则中心统一推送客户端通过注册监听器的方式时刻监听变化比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。规则持久化一致性快速引入第三方依赖原始模式如果不做任何修改Dashboard 的推送规则方式是通过 API 将规则推送至客户端并直接更新到内存这种做法的好处是简单⽆依赖坏处是应⽤重启规则就会消失仅⽤于简单测试不能⽤于⽣产环 境11.2 Pull 模式pull 模式的数据源如本地文件、RDBMS 等一般是可写入的。使用时需要在客户端注册数据源将对应的读数据源注册至对应的 RuleManager将写数据源注册至 transport 的WritableDataSourceRegistry中。以本地文件数据源为例1. 注册数据源import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource; import com.alibaba.csp.sentinel.datasource.FileWritableDataSource; import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.datasource.WritableDataSource; import com.alibaba.csp.sentinel.init.InitFunc; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import java.io.File; import java.io.IOException; import java.util.List; public class FileDataSourceInit implements InitFunc { Override public void init() throws Exception { String ruleDir System.getProperty(user.home) /sentinel/rules/orderService; String flowRulePath ruleDir /flow-rule.json; mkdirIfNotExist(ruleDir); createFileIfNotExist(flowRulePath); // 注册一个可读数据源用来定时读取本地的json文件更新到规则缓存中 ReadableDataSourceString, ListFlowRule ds new FileRefreshableDataSource( flowRulePath, source - JSON.parseObject(source, new TypeReferenceListFlowRule() { }) ); // 将可读数据源注册至FlowRuleManager // 这样当规则文件发生变化时就会更新规则到内存 FlowRuleManager.register2Property(ds.getProperty()); WritableDataSourceListFlowRule flowRuleWDS new FileWritableDataSource( flowRulePath, this::encodeJson ); // 将可写数据源注册至transport模块的WritableDataSourceRegistry中 // 这样收到控制台推送的规则时Sentinel会先更新到内存然后将规则写入到文件中 WritableDataSourceRegistry.registerFlowDataSource(flowRuleWDS); } private T String encodeJson(T t) { return JSON.toJSONString(t); } private void mkdirIfNotExist(String filePath) throws IOException { File file new File(filePath); if (!file.exists()) { file.mkdirs(); } } private void createFileIfNotExist(String filePath) throws IOException { File file new File(filePath); if (!file.exists()) { file.createNewFile(); } } }官方源代码2. 在 resources 下创建 META-INF/services 目录并创建文件com.alibaba.csp.sentinel.init.InitFunc写入本地数据源的路径com.xxx.xxx.FileDataSourceInitcom.ytvc.order.sentinel.FileDataSourceInit重启服务设置流控会发现流控规则同步到指定的文件中。文件路径示例C:\用户\lucf\sentinel\rules\orderService\flow-rule.json再次重启服务规则依然保存需要请求一下规则才可以看到修改配置文件可以看到控制台也得到了更新。配置文件说明JSON 示例[ { // 资源名 resource: /test, // 针对来源若为 default 则不区分调用来源 limitApp: default, // 限流阈值类型(1:QPS;0:并发线程数) grade: 1, // 阈值 count: 1, // 是否是集群模式 clusterMode: false, // 流控效果(0:快速失败;1:Warm Up(预热模式);2:排队等待) controlBehavior: 0, // 流控模式(0:直接;1:关联;2:链路) strategy: 0, // 预热时间秒预热模式需要此参数 warmUpPeriodSec: 10, // 超时时间排队等待模式需要此参数 maxQueueingTimeMs: 500, // 关联资源、入口资源(关联、链路模式) refResource: rrr } ]本地⽂件数据源会定时轮询⽂件的变更读取规则。这样我们既可以在应⽤本地直接修改⽂件来更新 规则也可以通过Sentinel控制台推送规则。以本地⽂件数据源为例推送过程如下图所⽰⾸先Sentinel控制台通过API将规则推送⾄客⼾端并更新到内存中接着注册的写数据源会将新的规 则保存到本地的⽂件中。使⽤pull模式的数据源时⼀般不需要对Sentinel控制台进⾏改造。这种实现⽅法好处是简单不引⼊新的依赖坏处是⽆法保证监控数据的⼀致性(就是需要自己再刷新一下)11.3 Push 模式生产环境下一般更常用的是 push 模式的数据源。对于 push 模式的数据源如远程配置中心ZooKeeper, Nacos, Apollo 等等推送的操作不应由 Sentinel 客户端进行而应该经控制台统一进行管理直接进行推送数据源仅负责获取配置中心推送的配置并更新到本地。因此推送规则正确做法应该是配置中心控制台/Sentinel 控制台 → 配置中心 → Sentinel 数据源 → Sentinel而不是经 Sentinel 数据源推送至配置中心。这样的流程就非常清晰了Sentinel 官方提供了 ZooKeeper, Redis, Nacos, Apollo, etcd等的动态数据源实现参考:dynamic-rule-configuration | Sentinel接下来以 Nacos 为例来讲解.参考官方案例:Sentinel/sentinel-extension/sentinel-datasource-nacos at master · alibaba/Sentinel① 规则下发控制台 → 配置中心Sentinel Dashboard或配置中心控制台会把你配置的限流 / 熔断规则写入远程配置中心比如 Nacos、ZooKeeper。这一步的核心是「统一存储」规则不再存在某个客户端的内存或本地文件里而是集中存放在配置中心。好处所有实例共享同一份配置天然保证了集群内的规则一致性。② 变更监听配置中心 → 客户端 Sentinel DataSource每个机器上的Sentinel DataSource会持续监听配置中心的规则变更当配置中心里的规则更新后会主动推送变更通知给所有客户端客户端收到通知后会拉取最新的规则内容。③ 规则生效DataSource → RuleManager内存客户端拉取到最新规则后会把规则更新到RuleManager中RuleManager就是 Sentinel 的内存规则管理器限流判断时直接读取这里的规则这一步完成后新规则就会立刻在当前机器上生效拦截请求。下载的路径Releases · alibaba/Sentinel解压进行源码的改造11.3.1 Nacos 官方支持依然是借助 Sentinel 的InitFuncSPI 扩展接口。只需要实现自己的InitFunc接口在init方法中编写注册数据源的逻辑。添加依赖dependency groupIdcom.alibaba.csp/groupId artifactIdsentinel-datasource-nacos/artifactId /dependency注册数据源import com.alibaba.csp.sentinel.datasource.ReadableDataSource; import com.alibaba.csp.sentinel.datasource.nacos.NacosDataSource; import com.alibaba.csp.sentinel.init.InitFunc; import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import java.util.List; public class NacosDataSourceInit implements InitFunc { // nacos server ip private static final String remoteAddress 47.108.157.13:8848; // nacos group private static final String groupId SENTINEL_GROUP; // nacos dataId private static final String dataId orderservice-flow-rules; Override public void init() throws Exception { ReadableDataSourceString, ListFlowRule flowRuleDataSource new NacosDataSource(remoteAddress, groupId, dataId, source - JSON.parseObject(source, new TypeReferenceListFlowRule() { })); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); } }配置数据源路径在resources下创建META-INF/services目录并创建文件com.alibaba.csp.sentinel.init.InitFunc文件中写入你实现类的全限定名com.bite.order.sentinel.NacosDataSourceInit配置 Nacos配置内容[ { clusterMode: false, controlBehavior: 0, count: 88.0, grade: 1, limitApp: default, maxQueueingTimeMs: 500, resource: /order/{orderId}, strategy: 0, warmUpPeriodSec: 10 } ]验证结果重启服务会发现 Sentinel Dashboard 已经从 nacos 获取规则配置信息了。修改 Nacos 文件发现 Sentinel Dashboard 会及时更新通过 Sentinel Dashboard 修改规则发现 Nacos 配置文件并没有同步更新。11.4 Sentinel 集成 Nacos 持久化上述我们发现Nacos 修改的内容会及时同步到 Sentinel DashBoard但是 Sentinel DashBoard 更新的内容并不会同步到 Nacos这在生产环境中也是不方便使用的。所以我们需要修改 Sentinel 的源码让其⽀持双向通讯