apollo动态切换mysql数据源_使用Apollo动态修改线上数据源

前言

最近需要实现一个功能,动态刷新线上数据源环境,下面来使用Apollo配置中心和Spring提供的AbstractRoutingDataSource来实现。

具体实现

Apollo是携程开源的统一配置中心,和springboot无缝衔接并且不需要安装其他软件就可以直接使用,可以实时推送最新的配置文件。Spring提供的AbstractRoutingDataSource用于动态管理数据源,可以动态更新数据源,一般数据库的读写分离也是用这个抽象类实现的。

对Apollo不熟悉的可以先了解一下,GitHub:https://github.com/ctripcorp/apollo

关于AbstractRoutingDataSource,介绍一下我们用到的方法

public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {

//传入的数据源

private Map targetDataSources;

//拿着子类实现的determineCurrentLookupKey()方法的返回值当做key在这个Map中寻找数据源

private Map resolvedDataSources;

//放入多个数据源

public void setTargetDataSources(Map targetDataSources) {

this.targetDataSources = targetDataSources;

}

//属性设置完成后执行

public void afterPropertiesSet() {

if (this.targetDataSources == null) {

throw new IllegalArgumentException("Property 'targetDataSources' is required");

} else {

this.resolvedDataSources = new HashMap(this.targetDataSources.size());

Iterator var1 = this.targetDataSources.entrySet().iterator();

while(var1.hasNext()) {

Entry entry = (Entry)var1.next();

Object lookupKey = this.resolveSpecifiedLookupKey(entry.getKey());

DataSource dataSource = this.resolveSpecifiedDataSource(entry.getValue());

this.resolvedDataSources.put(lookupKey, dataSource);

}

if (this.defaultTargetDataSource != null) {

this.resolvedDefaultDataSource = this.resolveSpecifiedDataSource(this.defaultTargetDataSource);

}

}

}

protected Object resolveSpecifiedLookupKey(Object lookupKey) {

return lookupKey;

}

//子类要实现的抽象方法,数据源的获取策略

protected abstract Object determineCurrentLookupKey();

}

下面来实现通过Apollo动态修改数据源:

@Configuration

public class DataSourceConfiguration {

private final static String DATASOURCE_TAG = "db";

@Autowired

ApplicationContext context;

@ApolloConfig

Config config;

@Bean("dataSource")

public DynamicDataSource dynamicDataSource() {

//使用springboot默认的连接池

DynamicDataSource source = new DynamicDataSource();

//只有一个数据源,传入的Map的key为db,value为使用的数据源

source.setTargetDataSources(Collections.singletonMap(DATASOURCE_TAG, dataSource()));

return source;

}

//Apollo监听配置是否修改

@ApolloConfigChangeListener

public void onChange(ConfigChangeEvent changeEvent) {

SetchangedKeys = changeEvent.changedKeys();

if (changedKeys.contains("spring.datasource.url")) {

DynamicDataSource source = context.getBean(DynamicDataSource.class);

//当检测到数据库地址改变时,重新设置数据源

source.setTargetDataSources(Collections.singletonMap(DATASOURCE_TAG, dataSource()));

//调用该方法刷新resolvedDataSources,下次获取数据源时将获取到新设置的数据源

source.afterPropertiesSet();

}

}

public DataSource dataSource() {

HikariDataSource dataSource = new HikariDataSource();

dataSource.setJdbcUrl(config.getProperty("spring.datasource.url", ""));

dataSource.setUsername(config.getProperty("spring.datasource.username", ""));

dataSource.setPassword(config.getProperty("spring.datasource.password", ""));

return dataSource;

}

//简单实现AbstractRoutingDataSource,因为只是有一个数据源,所以任何时候选择的数据源都一样

class DynamicDataSource extends AbstractRoutingDataSource {

@Override

protected Object determineCurrentLookupKey() { return DATASOURCE_TAG; }

}

}

determineCurrentLookupKey

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值