一、概述
正常情况下,业务开发中,Sentinel的限流或者熔断规则,是配置在项目本地通过SPI扩展点来实现的。而在系统设计的时候,这些模式需要配合业务量的预估、性能测试的数据进行相应阈值的配置,而这些阈值最好保存在配置中心,方便动态实时修改。
二、动态流控规则
Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:
通过 API 修改比较直观,可以通过以下几个 API 修改不同的规则:
FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则
DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则
2.1、动态规则的基本原理
由于loadRules()方法只能接受内存态的规则对象,但是在有一些场景中,限流是一个动态的行为,也就是规则可能存储于文件、数据库、配置中心。通过这种存储方式可以提供sentinel动态限流规则,如下图所示
2.2、DataSource
Sentinel提供了一个DataSource接口,这个接口为Sentinel提供了对接任意配置源的能力,相比于API的方式来修改规则,实现DataSource接口的方法更加灵活。
DataSource 扩展常见的实现方式有:
Sentinel 目前支持以下数据源扩展:
拉模式拓展 实现拉模式的数据源最简单的方式是继承 AutoRefreshDataSource 抽象类,然后实现readSource() 方法,在该方法里从指定数据源读取字符串格式的配置数据。比如 基于文件的数据源。
推模式拓展 实现推模式的数据源最简单的方式是继承 AbstractDataSource 抽象类,在其构造方法中添加监听器,并实现 readSource() 从指定数据源读取字符串格式的配置数据。比如 基于 Nacos 的数据源。
三、SPI 动态数据源demo
3.1、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文件中,添加自定义扩展点的全路径
3.2、扩展Nacos数据源
//添加Nacos Datasouce pom依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.8.0</version>
</dependency>
修改数据源加载方式(于SPI扩展的InitFunc来实现的)
public class DataSourceInitFunc implements InitFunc{
private final String remoteAddress="192.168.149.28"; //Nacos 远程服务host
private final String groupId="SENTINEL_GROUP"; //Nacos GroupID
private final String dataId="com.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上添加配置
四、配置文件的demo
spring.cloud.sentinel.transport.clientIp=192.168.149.28:7777
spring.cloud.sentinel.datasource.nacos.nacos.serverAddr=192.168.149.28:8848
spring.cloud.sentinel.datasource.nacos.nacos.dataId=com.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
五、集群限流
通常工作中只是基于Sentinel的基本使用和单机限流的使用,集群限流场景很少。
假如有这样一个场景,我们现在把provider部署了10个集群,希望调用这个服务的api的总的qps是100,意味着每一台机器的qps是10,理想情况下总的qps就是100,但是实际上由于负载均衡策略的流量分发并不是非常均匀的,就会导致总的qps不足100时,就被限了。在这个场景中,仅仅依靠单机来实现总体流量的控制是有问题的。所以最好是能实现集群限流。
集群流控中共有两种身份: