https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel
继上篇文章介绍Dashboard如何接入Apollo后,还剩下一个问题没解决,Sentinel Dashboard将流控规则推送到Apollo配置中心后,客户端如何实时监听到规则变化
在介绍客户端如何接入Apollo配置中心拉取流控规则之前,先介绍下JDK SPI机制
1、什么是SPI?
SPI的全名为Service Provider Interface,是JDK内置的一种服务提供发现机制,对于面向接口开发的Java来说,SPI使得开发者能够在不同模块/不同jar包对同一接口做不同实现
2、具体应用例子?
数据库驱动的加载,不同的数据库Oracle,Mysql等在Java中需要加载不同的驱动,JDK中加载驱动的顶层抽象接口为java.sql.Driver
再来看下Mysql驱动jar包中对应的实现
具体原理大家可以百度,只介绍到这里,只需要知道,我们可以在自己的项目/jar包中自定义SPI接口的实现,并在META-INF/services下指定自己的实现类来拓展接口实现
Sentinel中针对客户端的初始化操作,也预留了SPI接口com.alibaba.csp.sentinel.init.InitFunc,我们可以拓展该接口来实现客户端从Apollo中拉取规则相关逻辑,具体拉取逻辑,直接上代码,其中ApolloConfigUtil.getNamespaceName()为Apollo中存储规则的nameSpace,需要和dashboard推送规则的nameSpace一致
public class ApolloInitFunc implements InitFunc {
@Override
public void init() throws Exception {
String namespaceName = ApolloConfigUtil.getNamespaceName();
String defaultRules = "[]";
//流控规则
registerFlowRuleProperty(namespaceName, defaultRules);
//系统规则
registerSystemRuleProperty(namespaceName, defaultRules);
//热点规则
registerParamFlowRuleProperty(namespaceName, defaultRules);
//降级规则
registerDegradeRuleProperty(namespaceName, defaultRules);
//授权规则
registerAuthorityRuleProperty(namespaceName, defaultRules);
}
private void registerAuthorityRuleProperty(String namespaceName, String defaultRules) {
ReadableDataSource> authorityRuleDataSource = new ApolloDataSource<>(namespaceName,
ApolloConfigUtil.getAuthorityDataId(), defaultRules, source -> JSON.parseObject(source, new TypeReference>() {
}));
AuthorityRuleManager.register2Property(authorityRuleDataSource.getProperty());
}
private void registerDegradeRuleProperty(String namespaceName, String defaultRules) {
ReadableDataSource> degradeRuleDataSource = new ApolloDataSource<>(namespaceName,
ApolloConfigUtil.getDegradeDataId(), defaultRules, source -> JSON.parseObject(source, new TypeReference>() {
}));
DegradeRuleManager.register2Property(degradeRuleDataSource.getProperty());
}
private void registerParamFlowRuleProperty(String namespaceName, String defaultRules) {
ReadableDataSource> paramFlowRuleDataSource = new ApolloDataSource<>(namespaceName,
ApolloConfigUtil.getParamFlowDataId(), defaultRules, source -> JSON.parseObject(source, new TypeReference>() {
}));
ParamFlowRuleManager.register2Property(paramFlowRuleDataSource.getProperty());
}
private void registerSystemRuleProperty(String namespaceName, String defaultRules) {
ReadableDataSource> systemRuleDataSource = new ApolloDataSource<>(namespaceName,
ApolloConfigUtil.getSystemDataId(), defaultRules, source -> JSON.parseObject(source, new TypeReference>() {
}));
SystemRuleManager.register2Property(systemRuleDataSource.getProperty());
}
private void registerFlowRuleProperty(String namespaceName, String defaultRules) {
ReadableDataSource> flowRuleDataSource = new ApolloDataSource<>(namespaceName,
ApolloConfigUtil.getFlowDataId(), defaultRules, source -> JSON.parseObject(source, new TypeReference>() {
}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
}
}
注意点如下,最好客户端FastJson版本需要和Dashboard端保持一致,否则有可能出现奇怪的问题
第二步就是在META-INF/services下新建文件,并指定实现类路径了,比较简单,就不截图了。
最好的方案是将Apollo规则拉取相关代码、以及客户端连接Dashboard的地址配置都集成到一个SpringBoot Starter中供所有项目调用的,有兴趣的可以自己实现,不懂可以问我