3、Sentinel 动态限流规则-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Sentinel 的理念是开发者只需要关注资源的定义当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则

• 通过 API 直接修改 (loadRules)

• 通过 DataSource 适配不同数据源修改

通过 API 修改比较直观可以通过以下几个 API 修改不同的规则

FlowRuleManager.loadRules(List rules); // 修改流控规则
DegradeRuleManager.loadRules(List rules); // 修改降级规则
手动修改规则硬编码方式一般仅用于测试和演示生产上一般通过动态规则源的方式来动态管理规则。

3.1 DataSource
上述 loadRules() 方法只接受内存态的规则对象但更多时候规则存储在文件、数据库或者配置中心当中。DataSource 接口给我们提供了对接任意配置源的能力。相比直接通过 API 修改规则实现 DataSource 接口是更加可靠的做法。

我们推荐通过控制台设置规则后将规则推送到统一的规则中心客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更流程如下
在这里插入图片描述
DataSource 扩展常见的实现方式有:

• 拉模式客户端主动向某个规则管理中心定期轮询拉取规则这个规则中心可以是 RDBMS、文件甚至是 VCS 等。这样做的方式是简单缺点是无法及时获取变更

• 推模式规则中心统一推送客户端通过注册监听器的方式时刻监听变化比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。

Sentinel 目前支持以下数据源扩展

• Pull-based: 动态文件数据源、Consul, Eureka

• Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd

2.3.2 poll
实现拉模式的数据源最简单的方式是继承AutoRefreshDataSource抽象类然后实现 readSource() 方法在该方法里从指定数据源读取字符串格式的配置数据。比如基于文件的数据源

2.3.3 push
实现推模式的数据源最简单的方式是继承AbstractDataSource抽象类在其构造方法中添加监听器并实现 readSource() 从指定数据源读取字符串格式的配置数据。基于 Nacos 的数据源

2.3.4 注册数据源
通常需要调用以下方法将数据源注册至指定的规则管理器中

ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());

若不希望手动注册数据源可以借助 Sentinel 的 InitFunc SPI 扩展接口。只需要实现自己的 InitFunc 接口在 init 方法中编写注册数据源的逻辑。比如

package com.test.init;

public class DataSourceInitFunc implements InitFunc {

    @Override
    public void init() throws Exception {
        final String remoteAddress = "localhost";
        final String groupId = "Sentinel:Demo";
        final String dataId = "com.alibaba.csp.sentinel.demo.flow.rule";

        ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId,
            source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
        FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
    }
}

接着将对应的类名添加到位于资源目录通常是 resource 目录下的 META-INF/services 目录下的 com.alibaba.csp.sentinel.init.InitFunc 文件中比如

com.test.init.DataSourceInitFunc
这样当初次访问任意资源的时候Sentinel 就可以自动去注册对应的数据源了。

2.3.5 示例
代码见springboot-sentinel1项目

2.3.5.1 InitFunc
可以通过Sentinel的InitFunc SPI来实现接口的扩展从而配置限流规则

public class FlowRuleInitFunc implements InitFunc{
  @Override
  public void init() throws Exception {
    List<FlowRule> rules=new ArrayList<>();
    FlowRule rule=new FlowRule();
    rule.setResource("doTest");
    rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
    rule.setCount(5);
    rules.add(rule);
    FlowRuleManager.loadRules(rules);
 }
}

• 在META-INF/services/com.alibaba.csp.sentinel.init.InitFunc文件中添加自定义扩展点的全路径

• 重启服务之后会触发限流。

2.3.2.2 扩展Nacos数据源
• 添加Nacos Datasouce依赖

<dependency>
  <groupId>com.alibaba.csp</groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
  <version>1.8.0</version>
</dependency>

• 修改数据源加载方式

public class DataSourceInitFunc implements InitFunc{
  private final String remoteAddress="192.168.216.128"; //Nacos 远程服务host
  private final String groupId="SENTINEL_GROUP"; //Nacos GroupID
  private final String dataId="com.gupaoedu.sentinel.demo.flow.rule";
  @Override
  public void init() throws Exception {
    ReadableDataSource<String,List<FlowRule>> flowRuleDataSource=
        new NacosDataSource<>(remoteAddress,groupId,dataId,
            source-> JSON.parseObject(source,new
TypeReference<List<FlowRule>>(){}));
    FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
 }
}

• 在Nacos上添加配置
在这里插入图片描述
• 通过访问测试即可看到被限流的效果。

• 也可以在 ${用户}/logs/csp/sentinel-record.log.2020-09-22 文件中看到sentinel启动过程中动态数据源的加载过程。

2.3.6 基于配置文件
基于配置文件的动态限流

spring.cloud.sentinel.transport.clientIp=192.168.216.128:7777
spring.cloud.sentinel.datasource.nacos.nacos.serverAddr=192.168.216.128:8848
spring.cloud.sentinel.datasource.nacos.nacos.dataId=com.gupaoedu.sentinel.demo.flow.rule
spring.cloud.sentinel.datasource.nacos.nacos.groupId=SENTINEL_GROUP
spring.cloud.sentinel.datasource.nacos.nacos.dataType=json
spring.cloud.sentinel.datasource.nacos.nacos.ruleType=flow
spring.cloud.sentinel.datasource.nacos.nacos.username=nacos
spring.cloud.sentinel.datasource.nacos.nacos.password=nacos
阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6