看过ShardingSphere4.0.0-RC1实现动态刷新actualDataNodes,不使用zookeeper等第三方注册中心这篇文章,但是发现其可操作性还是写的太差,很多还需要自己琢磨,故此写下这篇文章记录自己的琢磨过程
需要引入sharding的服务编排核心jar包,举例:gradle
compile group: 'org.apache.shardingsphere', name: 'sharding-orchestration-core', version: '4.0.1'
接着引包
compile group: 'org.apache.shardingsphere', name: 'sharding-jdbc-orchestration-spring-namespace', version: '4.0.1'
关于sharding SPI方面的说明请自行查看官方文档
org.apache.shardingsphere.orchestration.reg.api.RegistryCenter
com.changan.carbond.shardingjdbc.LocalRegistryCenter
com.xstudio.shardingjdbc.LocalRegistryCenter
和上述类保持一致【SPI注册】public class LocalRegistryCenter implements RegistryCenter {
public static Map<String, DataChangedEventListener> listeners = new ConcurrentHashMap<>();
private RegistryCenterConfiguration config;
private Properties properties;
/**
* public 是为了在重置节点的时候减少去重新读配置
*/
public static Map<String, String> values = new ConcurrentHashMap<>();
@Override
public void init(RegistryCenterConfiguration config) {
this.config = config;
}
@Override
public String get(String key) {
return values.get(key);
}
@Override
public String getDirectly(String key) {
return values.get(key);
}
@Override
public boolean isExisted(String key) {
return values.containsKey(key);
}
@Override
public List<String> getChildrenKeys(String key) {
return null;
}
@Override
public void persist(String key, String value) {
values.put(key, value);
}
@Override
public void update(String key, String value) {
values.put(key, value);
}
@Override
public void persistEphemeral(String key, String value) {
values.put(key, value);
}
@Override
public void watch(String key, DataChangedEventListener dataChangedEventListener) {
if (null != dataChangedEventListener) {
// 将数据改变的事件监听器缓存下来
listeners.put(key, dataChangedEventListener);
}
}
@Override
public void close() {
config = null;
}
@Override
public void initLock(String key) {
}
@Override
public boolean tryLock() {
return false;
}
@Override
public void tryRelease() {
}
@Override
public String getType() {
// 【关键点1】,留着文章后续引用
return "shardingLocalRegisterCenter";
}
@Override
public Properties getProperties() {
return properties;
}
@Override
public void setProperties(Properties properties) {
LocalRegistryCenter.properties = properties;
}
}
// 数据源设置
Map<String, DataSource> dataSourceMap = new LinkedHashMap<>();
dataSourceMap.put("哈哈", dataSource);
// 属性设置
Properties properties = new Properties();
properties.setProperty("sql.show", "false");
OchestrationConfiguration configuration = new OrchestrationConfiguration("【关键点2】",
new RegistryCenterConfiguration("【关键点1】的值"),
false);
OrchestrationShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, properties, configuration)
这边对服务开了一个api接口,方便外部调用触发重新加载节点
// 获取已有的配置
String rules = LocalRegistryCenter.values.get("/【关键点2】/config/schema/logic_db/rule");
// 省略改rule的逻辑,可以字符串替换什么的,我是这样操作的
String newRule = rules.replace("...","...");
LocalRegistryCenter.listeners.get("/【关键点2】/config/schema")
.onChange(new DataChangedEvent("/【关键点2】/config/schema/logic_db/rule", newRule, DataChangedEvent.ChangedType.UPDATED));