装饰网站的业务员都是怎么做的,wordpress淘点金插件,唯美wordpress简约主题,网站建设意向书一、Sentinel Dashboard 规则联动持久化方案
Sentinel 是阿里开源的一个流量控制组件#xff0c;它提供了一种流量控制、熔断降级、系统负载保护等功能的解决方案。并且我们通过 Sentinel Dashboard 可以非常便捷的添加或修改规则策略#xff0c;但是如果细心的小伙伴应该可…一、Sentinel Dashboard 规则联动持久化方案
Sentinel 是阿里开源的一个流量控制组件它提供了一种流量控制、熔断降级、系统负载保护等功能的解决方案。并且我们通过 Sentinel Dashboard 可以非常便捷的添加或修改规则策略但是如果细心的小伙伴应该可以发现默认情况下通过 Sentinel Dashboard 添加或修改的规则并没有进行持久化服务重启后先前的规则也就消失了这对于生产环境肯定是不允许的那如何进行持久化操作呢
Sentinel 官方已经提供了几种持久化方案比如可以将规则存放在 Nacos、Redis、ZK、Apollo 等等但是这些操作都没有和 Sentinel Dashboard 做联动我们需要手动编写规则如 json 格式存放在持久化引擎中。
这里我以 Nacos 为例通过添加 sentinel-datasource-nacos 依赖可以将配置持久化到 Nacos 配置引擎中
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-nacos/artifactId
/dependency比如我们将如下配置在 Nacos 中
[{resource: mylimit,controlBehavior: 0,count: 1.0,grade: 1,limitApp: default,strategy: 0}
]此时可以在 Sentinel Dashboard 中看到该规则 但是返回来在 Sentinel Dashboard 添加或修改的规则并没有反向持久化到 Nacos 中并且随着服务的重启修改的规则会丢失。 因此解决上述问题可以从两个方向入手一个是拉模式、一个是推模式
拉模式通过 sentinel-datasource-extension 包扩展读数据源RefreshableDataSource定期扫描目标数据源比如服务器下的某个文件如果发生变动便加载到内存中。以及写数据源 WritableDataSource 当在 Sentinel Dashboard 中变动规则时 由服务同步将规则持久化到数据源中。 推模式服务通过监有事件通知能力的目标数据源如 nacos、redis、zk、Apollo 等当目标数据源中的规则发生变动时通过事件监听通知服务更新规则而 Sentinel Dashboard 则不直接将规则发往服务而是主动持久化到目标数据源中。这种方式需要修改 Sentinel Dashboard 的源码将原先的通知逻辑修改为存储到目标数据源。 两种方式都有各自的优缺点例如 拉模式 下如果主动改动数据源的数据需要等到下次扫描时才能生效而 推模式 由于采用事件监听的方式可以保证修改的实时性。但是 拉模式 下无需修改源码在官方提供的依赖基础上就可以实现而推模式 需要根据源码定制化开发需求。
下面一起实践下两种方案。
为了方便后续的测试这里提前创建一个接口指定资源名称为 r1
RestController
RequestMapping(/test)
public class TestController {SentinelResource(value r1,blockHandler blockHandler)GetMapping(/t1)public String t1(){return success;}public String blockHandler(BlockException exception){return 降级了;}}二、拉模式
首先需要引入 sentinel-datasource-extension 依赖
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-datasource-extension/artifactId
/dependency这里使用本地文件的方式存储规则也是 extension 依赖中已经实现好的方式如果需要存储到其他数据源中可以模仿 FileRefreshableDataSource 以及 FileWritableDataSource 进行修改。并且还需要实现 InitFunc接口在init方法中指定DataSource初始化逻辑并利用spi机制实现加载。
对于规则 Sentinel 中有多种类型这里实现了 流量、熔断、权限、系统 四个方面的规则持久化
public class FileDataSourceInit implements InitFunc {/*** 规则文件*/private static final String RULE_FILE_PATH System.getProperty(user.dir) File.separator;private static final String FLOW_RULE_FILE_NAME FlowRule.json;private static final String DEGRADE_RULE_FILE_NAME DegradeRule.json;private static final String AUTHORITY_RULE_FILE_NAME AuthorityRule.json;private static final String SYSTEM_RULE_FILE_NAME SystemRule.json;Overridepublic void init() throws Exception {disposeRules();}private void disposeRules() throws FileNotFoundException {String flowRuleFilePath RULE_FILE_PATH FLOW_RULE_FILE_NAME;String degradeRuleFilePath DEGRADE_RULE_FILE_NAME FLOW_RULE_FILE_NAME;String authorityRuleFilePath AUTHORITY_RULE_FILE_NAME FLOW_RULE_FILE_NAME;String systemRuleFilePath SYSTEM_RULE_FILE_NAME FLOW_RULE_FILE_NAME;FileRefreshableDataSourceListFlowRule flowRuleRead new FileRefreshableDataSource(flowRuleFilePath, source - JSON.parseObject((String) source,new TypeReferenceListFlowRule() {}));FileRefreshableDataSourceListDegradeRule degradeRuleRead new FileRefreshableDataSource(degradeRuleFilePath, source - JSON.parseObject((String) source,new TypeReferenceListDegradeRule() {}));FileRefreshableDataSourceListAuthorityRule authorityRuleRead new FileRefreshableDataSource(authorityRuleFilePath, source - JSON.parseObject((String) source,new TypeReferenceListAuthorityRule() {}));FileRefreshableDataSourceListSystemRule systemRuleRead new FileRefreshableDataSource(systemRuleFilePath, source - JSON.parseObject((String) source,new TypeReferenceListSystemRule() {}));FlowRuleManager.register2Property(flowRuleRead.getProperty());DegradeRuleManager.register2Property(degradeRuleRead.getProperty());SystemRuleManager.register2Property(systemRuleRead.getProperty());AuthorityRuleManager.register2Property(authorityRuleRead.getProperty());WritableDataSourceListFlowRule flowRuleData new FileWritableDataSource(flowRuleFilePath, this::encodeJson);WritableDataSourceListDegradeRule degradeRuleData new FileWritableDataSource(degradeRuleFilePath, this::encodeJson);WritableDataSourceListAuthorityRule authorityRuleData new FileWritableDataSource(authorityRuleFilePath, this::encodeJson);WritableDataSourceListSystemRule systemRuleData new FileWritableDataSource(systemRuleFilePath, this::encodeJson);WritableDataSourceRegistry.registerFlowDataSource(flowRuleData);WritableDataSourceRegistry.registerDegradeDataSource(degradeRuleData);WritableDataSourceRegistry.registerSystemDataSource(systemRuleData);WritableDataSourceRegistry.registerAuthorityDataSource(authorityRuleData);}private T String encodeJson(T t) {return JSON.toJSONString(t);}}然后在 resources 下创建 META-INF.services 包然后在该包下新建 com.alibaba.csp.sentinel.init.InitFunc 文件文件的内容就是上面类的完整包名地址 然后启动项目在 Sentinel Dashboard 中添加一个规则 可以在项目根目录发现已经创建了 FlowRule.json 文件并且存储的内容就是 JSON 格式的规则信息 如果此时将服务重启再次查看 Sentinel Dashboard 可以发现原有的规则依然存在。
并且多次访问 t1 测试接口可以看到规则依然有效 三、推模式
推模式下可以通过事件监听更及时的通知到目标服务这里采用 Nacos 作为目标数据源进行实验。上面实验拉模式可以感觉出 Sentinel 不同类型的规则是单独控制的这里为了方便演示以流量规则的修改为例进行实践。
同时做好Nacos中配置文件名的约定为 {application name}-sentinel-{type}例如这里的实验项目名称为 sentinel-demo 的流量规则的名字为sentinel-demo-sentinel-flow。
在 Nacos 中创建目标配置 然后在目标服务中配置flow规则指向该配置 上面提到推模式需要修改源码这里先将 Sentinel 的源码拉取下来
git clone https://github.com/alibaba/Sentinel.git使用 IDEA 打开项目其中 sentinel-dashboard 就是下面我们需要修改的项目 从Sentinel1.4.0开始sentinel-dashboard项目就提供了 DynamicRulePublisher和DynamicRuleProvider 两个接口用于实现自定义的规则推送和拉取操作因此我们后续的操作也是基于这两个接口 首先在该项目中加入 nacos-client 的依赖
dependencygroupIdcom.alibaba.nacos/groupIdartifactIdnacos-client/artifactIdversion1.4.2/version
/dependency先实现一个 RuleNacosConfig 类用来定义和 Nacos 的约定信息以及声明出 ConfigService
Configuration
public class RuleNacosConfig {/*** Nacos 配置所在组*/public static final String GROUP_ID DEFAULT_GROUP;/*** Nacos 流量规则的名称后缀*/public static final String FLOW_DATA_ID_POSTFIX -sentinel-flow;/*** Nacos 信息, 最好读取配置信息这里演示先写死*/Beanpublic ConfigService nacosConfigService() throws Exception {return ConfigFactory.createConfigService(127.0.0.1:8848);}
}实现 DynamicRuleProvider 根据不同的服务从 Nacos 中拉取配置
Component(flowRuleNacosProvider)
public class FlowRuleNacosProvider implements DynamicRuleProviderListFlowRuleEntity {Autowiredprivate ConfigService configService;Overridepublic ListFlowRuleEntity getRules(String appName) throws Exception {String rules configService.getConfig(appName RuleNacosConfig.FLOW_DATA_ID_POSTFIX,RuleNacosConfig.GROUP_ID, 3000);if (StringUtil.isEmpty(rules)) {return new ArrayList();}return JSON.parseArray(rules, FlowRuleEntity.class);}
}然后实现 DynamicRulePublisher 将修改后的规则持久化到 Nacos
Component(flowRuleNacosPublisher)
public class FlowRuleNacosPublisher implements DynamicRulePublisherListFlowRuleEntity {Autowiredprivate ConfigService configService;Overridepublic void publish(String app, ListFlowRuleEntity rules) throws Exception {if (StringUtils.isBlank(app)) {throw new RuntimeException(Server app is null!);}if (rules null) {return;}configService.publishConfig(app RuleNacosConfig.FLOW_DATA_ID_POSTFIX,RuleNacosConfig.GROUP_ID, JSON.toJSONString(rules));}
}接着修改 com.alibaba.csp.sentinel.dashboard.controller.FlowControllerV1 类先将上面创建的 FlowRuleNacosProvider 和 FlowRuleNacosPublisher 注入进来 下面需要修改 /rules 和 /rule 两个接口使用上面我们自定义逻辑首先在 /rules 接口中注释掉原来的 sentinelApiClient.fetchFlowRuleOfMachine 替换成
ListFlowRuleEntity rules flowRuleNacosProvider.getRules(app);然后在 /rule 接口注释掉 publishRules 方法的调用换成
flowRuleNacosPublisher.publish(entity.getApp(), repository.findAllByApp(entity.getApp()));停止掉原有的 Sentinel Dashboard 控制台服务然后本地启动新的 Sentinel Dashboard 服务或者打包成 jar 包后启动 。
浏览器访问新的 Sentinel Dashboard 控制台。
这里测试增加一个流控规则 下面查看 Nacos 中对应的配置内容 已经主动持久化到 Nacos 中了并且多次访问测试接口规则也依然生效 到此整个修改过程就结束了虽然上面仅针对流量控制进行了整合其他模式也是一样的处理方式有兴趣的小伙伴可以继续补充完善。