比如我们希望控制对资源 test 的访问设置白名单,只有来源为 appA 和 appB 的请求才可通过,则可以配置如下白名单规则:
AuthorityRule rule = new AuthorityRule(); rule.setResource("test"); rule.setStrategy(RuleConstant.AUTHORITY_WHITE); rule.setLimitApp("appA,appB"); AuthorityRuleManager.loadRules(Collections.singletonList(rule)); 动态规则 规则Sentinel 的理念是开发者只需要关注资源的定义,当资源定义成功后可以动态增加各种流控降级规则。Sentinel 提供两种方式修改规则:
通过 API 直接修改 (loadRules)
通过 DataSource 适配不同数据源修改
手动通过 API 修改比较直观,可以通过以下几个 API 修改不同的规则:
FlowRuleManager.loadRules(List<FlowRule> rules); // 修改流控规则 DegradeRuleManager.loadRules(List<DegradeRule> rules); // 修改降级规则手动修改规则(硬编码方式)一般仅用于测试和演示,生产上一般通过动态规则源的方式来动态管理规则。
DataSource 扩展上述 loadRules() 方法只接受内存态的规则对象,但更多时候规则存储在文件、数据库或者配置中心当中。DataSource 接口给我们提供了对接任意配置源的能力。相比直接通过 API 修改规则,实现 DataSource 接口是更加可靠的做法。
我们推荐通过控制台设置规则后将规则推送到统一的规则中心,客户端实现 ReadableDataSource 接口端监听规则中心实时获取变更,流程如下:
DataSource 扩展常见的实现方式有:
拉模式:客户端主动向某个规则管理中心定期轮询拉取规则,这个规则中心可以是 RDBMS、文件,甚至是 VCS 等。这样做的方式是简单,缺点是无法及时获取变更;
推模式:规则中心统一推送,客户端通过注册监听器的方式时刻监听变化,比如使用 Nacos、Zookeeper 等配置中心。这种方式有更好的实时性和一致性保证。
Sentinel 目前支持以下数据源扩展:
Pull-based: 动态文件数据源、Consul, Eureka
Push-based: ZooKeeper, Redis, Nacos, Apollo, etcd
示例 1、启动本地的nacosnacos下载地址
启动文件在``nacos/bin`目录下面
startup.cmd -m standalone :代表单机启动的意思
2、向nacos中添加限制规则 /** * 向nacos中发送配置 */ fun send() { val remoteAddress = "localhost" val groupId = "Sentinel:Demo" val dataId = "com.alibaba.csp.sentinel.demo.flow.rule" val rule = """[ { "resource": "TestResource", "controlBehavior": 0, "count": 5.0, "grade": 1, "limitApp": "default", "strategy": 0 } ]""" val configService = NacosFactory.createConfigService(remoteAddress) println(configService.publishConfig(dataId, groupId, rule)) } 3、从nacos中读取配置规则 // remoteAddress 代表 Nacos 服务端的地址 val remoteAddress = "127.0.0.1" // groupId 和 dataId 对应 Nacos 中相应配置 val groupId = "Sentinel:Demo" val dataId = "com.alibaba.csp.sentinel.demo.flow.rule" /** * 加载规则 */ fun loadRules() { val flowRuleDataSource: NacosDataSource<List<FlowRule?>> = NacosDataSource<List<FlowRule?>>( remoteAddress, groupId, dataId ) { source: String? -> JSON.parseObject<List<FlowRule?>>( source, object : TypeReference<List<FlowRule?>?>() {}) } FlowRuleManager.register2Property(flowRuleDataSource.property) }