Spring Cloud Alibaba 架构-Sentinel动态扩展

12 篇文章 0 订阅
10 篇文章 0 订阅

规则

Sentinel 的动态扩展功能是其作为一个强大的流量控制和服务治理框架的重要组成部分。

1. 动态规则扩展

  • API 直接修改:通过 Sentinel 提供的 API,如 FlowRuleManager.loadRules(),可以动态加载或修改流量控制、熔断降级等规则。这种方式适用于临时或测试场景。
  • DataSource 支持:Sentinel 支持通过 DataSource 加载规则,可以从文件、数据库、配置中心等多种数据源动态加载规则。这提供了更高的灵活性和实时性,适合生产环境使用。
    • 原始模式:定期从数据源拉取规则。
    • 拉模式:Sentinel 主动从数据源拉取规则。
    • 推模式:数据源主动将规则推送到 Sentinel,例如使用 Nacos、Apollo 等配置中心时。

API 直接修改

API 修改可以通过以下几个 API 修改不同的规则:

FlowRuleManager.loadRules(List<FlowRule> rules):加载或更新流量控制规则。
DegradeRuleManager.loadRules(List<DegradeRule> rules):加载或更新熔断降级规则。
SystemRuleManager.loadRules(List<SystemRule> rules):加载或更新系统规则,如系统负载保护规则。
AuthorityRuleManager.loadRules(List<AuthorityRule> rules):加载或更新授权规则。
ParamFlowRuleManager.loadRules(List<ParamFlowRule> rules):加载或更新热点参数限流规则。

DataSource 支持

三种模式:

推送模式说明优点缺点
原始模式API 将规则推送至客户端并直接更新到内存中,扩展写数据源(WritableDataSource)简单,无任何依赖不保证一致性;规则保存在内存中,重启即消失。严重不建议用于生产环境
Pull 模式扩展写数据源(WritableDataSource), 客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件 等简单,无任何依赖;规则持久化不保证一致性;实时性不保证,拉取过于频繁也可能会有性能问题。
Push 模式扩展读数据源(ReadableDataSource),规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。生产环境下一般采用 push 模式的数据源。规则持久化;一致性;快速引入第三方依赖

推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更,流程如下:
在这里插入图片描述
DataSource 扩展常见的实现方式主要包括两种:拉模式(Pull-based)推模式(Push-based)
1. 拉模式(Pull-based)
在拉模式中,Sentinel 的客户端会主动向某个规则管理中心(如文件、RDBMS、VCS 等)定期轮询拉取规则。这种方式的实现相对简单,但存在一个明显的缺点,即无法及时获取规则的变更。因为 Sentinel 客户端是定期拉取规则,所以在规则发生变更和 Sentinel 客户端下次拉取规则之间会存在一个时间差。
2. 推模式(Push-based)
在推模式中,规则中心会统一推送规则变更到 Sentinel 客户端。Sentinel 客户端通过注册监听器的方式时刻监听规则的变化。一旦规则中心发生规则变更,就会立即推送到所有注册的 Sentinel 客户端,从而实现规则的实时更新。推模式通常使用配置中心(如 Nacos、Zookeeper、Apollo 等)作为规则中心。

Sentinel 支持的数据源

Pull-based:

  • 文件:FileRefreshableDataSource 会周期性地读取文件以获取规则,当文件有更新时会及时发现,并将规则更新到内存中。
<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-datasource-extension</artifactId>
   <version>x.y.z</version>
</dependency>
  • Consul(虽然未在参考文章中明确提到,但 Sentinel 通常也支持 Consul 作为数据源)
<dependency>
 <groupId>com.alibaba.csp</groupId>
 <artifactId>sentinel-datasource-consul</artifactId>
 <version>x.y.z</version>
</dependency>

创建ConsulDataSource

ReadableDataSource<String, List<FlowRule>> dataSource = new ConsulDataSource<>(host, port, ruleKey, waitTimeoutInSecond, flowConfigParser);
FlowRuleManager.register2Property(dataSource.getProperty());

Push-based:

  • ZooKeeper
<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-zookeeper</artifactId>
  <version>x.y.z</version>
</dependency>

然后创建 ZookeeperDataSource 并将其注册至对应的 RuleManager 上即可。比如:

// remoteAddress 代表 ZooKeeper 服务端的地址
// path 对应 ZK 中的数据路径
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
  • Redis
<!-- 仅支持 JDK 1.8+ -->
<dependency>
   <groupId>com.alibaba.csp</groupId>
   <artifactId>sentinel-datasource-redis</artifactId>
   <version>x.y.z</version>
</dependency>

Redis 动态配置源采用 Redis PUB-SUB 机制实现

ReadableDataSource<String, List<FlowRule>> redisDataSource = new RedisDataSource<List<FlowRule>>(redisConnectionConfig, ruleKey, channel, flowConfigParser);
FlowRuleManager.register2Property(redisDataSource.getProperty());
  • Nacos
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>x.y.z</version>
</dependency>

然后创建 NacosDataSource 并将其注册至对应的 RuleManager 上即可。比如:

// remoteAddress 代表 Nacos 服务端的地址
// groupId 和 dataId 对应 Nacos 中相应配置
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
    source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
  • Apollo
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-apollo</artifactId>
    <version>x.y.z</version>
</dependency>

然后创建 ApolloDataSource 并将其注册至对应的 RuleManager 上即可。比如:

// namespaceName 对应 Apollo 的命名空间名称
// ruleKey 对应规则存储的 key
// defaultRules 对应连接不上 Apollo 时的默认规则
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ApolloDataSource<>(namespaceName, ruleKey, defaultRules, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
  • etcd
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-etcd</artifactId>
    <version>x.y.z</version>
</dependency>

创建ECTD DataSource

// `rule_key` is the rule config key
ReadableDataSource<String, List<FlowRule>> flowRuleEtcdDataSource = new EtcdDataSource<>(rule_key, (rule) -> JSON.parseArray(rule, FlowRule.class));
FlowRuleManager.register2Property(flowRuleEtcdDataSource.getProperty());

2.初始化逻辑扩展

  • Sentinel 提供了 InitFunc 接口,允许开发者注册自定义的初始化逻辑。这些逻辑可以在应用首次访问 Sentinel 保护的资源时执行,如注册动态规则源、设置统计回调等。
  • 通过注解可以设置 InitFunc 的执行优先级,确保初始化逻辑按预期顺序执行。
    在Sentinel的源码中,会看到类似InitExecutor的组件,它负责执行这些InitFunc。在InitExecutor的doInit()方法中,通常会遍历并执行所有注册的InitFunc。
    InitFunc包括:
  1. CommandCenterInitFunc:用于初始化命令中心相关的功能,如接收来自控制台的命令等。
  2. HeartbeatSenderInitFunc:用于初始化心跳发送相关的功能,如定期向控制台发送心跳数据等。
  3. DefaultClusterClientInitFuncDefaultClusterServerInitFunc:用于初始化集群客户端和集群服务器相关的功能。
  4. MetricCallbackInit:用于初始化度量回调相关的功能,如设置度量数据的处理逻辑等。
  5. ParamFlowStatisticSlotCallbackInit:用于初始化热点参数限流统计槽的回调功能。

这些InitFunc的实现取决于Sentinel的具体使用场景和配置。例如,如果使用Sentinel的集群模式,那么可能需要实现与集群相关的InitFunc;如果使用Sentinel与Nacos等配置中心集成,那么可能需要实现与配置中心相关的InitFunc。

3. Slot Chain 扩展

  • Sentinel 的核心处理逻辑通过一系列的 Slot 组成的 Slot Chain 来实现。这些 Slot 负责不同的功能,如流量控制、熔断降级、系统保护等。
  • Sentinel 允许开发者自定义 Slot 并将其添加到 Slot Chain 中,从而扩展 Sentinel 的功能。这为用户提供了高度的灵活性和可定制性。
  • 自定义 Slot 可以实现特定的业务逻辑,如与第三方服务集成、自定义限流算法等。
    自定义的 Slot Chain 扩展步骤:
  1. 定义自定义 Slot:首先,你需要定义一个实现了 Sentinel Slot 接口的类。这个类将包含你的自定义逻辑,例如特定的规则检查、数据统计等。
  2. 创建 CustomSlotChainBuilder:接下来,你需要创建一个 CustomSlotChainBuilder 类,该类继承了 Sentinel 的默认 SlotChainBuilder 类或实现了类似的接口。在这个类中,你可以添加你的自定义 Slot 到 Slot Chain 中,并定义它们之间的顺序。
  3. 配置 CustomSlotChainBuilder:在你的应用中,你需要配置 Sentinel 使用你的 CustomSlotChainBuilder 而不是默认的 SlotChainBuilder。这通常可以通过配置文件、注解或代码来实现。
  4. 测试和验证:最后,你需要测试和验证你的自定义 Slot Chain 是否按预期工作。你可以编写单元测试或集成测试来模拟不同的场景和流量模式,并检查 Sentinel 是否正确地执行了你的自定义逻辑。

请注意,Sentinel 的 SPI 扩展机制可能需要一定的编程经验和知识。如果不熟悉这个领域,可能需要先学习一些相关的概念和技术。此外,Sentinel 的官方文档和社区资源也是学习和实现自定义 Slot Chain 扩展。可以查看 Sentinel 的官方文档以了解更多关于 SPI 扩展的信息和示例代码,也可以参与 Sentinel 的社区讨论以获取帮助和支持。

4. 扩展点 SPI

  • Sentinel 采用了基于 Java SPI(Service Provider Interface)的扩展机制,允许开发者通过实现特定的接口来扩展 Sentinel 的功能。
  • Sentinel 提供了多个扩展点,如 SlotChainBuilder、DataSource、TokenGenerator 等,开发者可以根据需要实现这些接口来扩展 Sentinel。
    自定义的扩展点,需要遵循以下步骤:
  1. 定义接口:首先,需要定义一个Java接口作为扩展点的规范。这个接口应该包含扩展点所需的所有方法。
  2. 实现接口:然后,用户需要实现这个接口,并编写自定义的扩展逻辑。
  3. 配置扩展点:在应用程序中,用户需要配置Sentinel使用自定义的扩展点实现。这通常可以通过配置文件、注解或代码来实现。
  4. 测试和验证:最后,用户需要测试和验证自定义的扩展点是否按预期工作。这可以通过编写单元测试、集成测试或模拟实际场景来完成。

5. 实时性

  • Sentinel 的动态扩展功能保证了规则的实时生效,无需重启应用即可更新规则。
  • 通过配置中心(如 Nacos)推送规则时,Sentinel 可以实时感知并应用新的规则,确保系统的稳定性和可用性。

动态扩展在实时性方面提供了多种方式,其中通过 DataSource 适配不同数据源修改规则是一种常见且推荐的使用方式。这种方式允许 Sentinel 从不同的数据源(如文件、数据库、配置中心等)动态加载和更新规则,从而确保规则的实时性和一致性。
DataSource 的扩展实现中,推模式(Push-based)通常具有更好的实时性和一致性保证。推模式通过规则中心统一推送规则变更到 Sentinel 客户端,客户端通过注册监听器的方式时刻监听规则的变化。一旦规则中心发生规则变更,就会立即推送到所有注册的 Sentinel 客户端,实现规则的实时更新。
在生产环境下,为了获得更好的实时性和一致性保证,通常会采用推模式的数据源。通过配置 Nacos、Zookeeper 等配置中心作为规则中心,可以实现 Sentinel 规则的动态更新和实时生效。

总结

Sentinel 的动态扩展功能为用户提供了高度的灵活性和可定制性,使得 Sentinel 能够适应各种复杂的分布式系统场景。通过动态规则扩展、初始化逻辑扩展、Slot Chain 扩展以及扩展点 SPI,开发者可以轻松地扩展 Sentinel 的功能,实现自定义的流量控制和服务治理策略。这些功能使得 Sentinel 成为了分布式系统中不可或缺的流量控制和服务治理框架。

  • 33
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值