zoukankan      html  css  js  c++  java
  • 使用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<Object, Object> targetDataSources;
    
         //拿着子类实现的determineCurrentLookupKey()方法的返回值当做key在这个Map中寻找数据源
        private Map<Object, DataSource> resolvedDataSources;
    
        //放入多个数据源
        public void setTargetDataSources(Map<Object, Object> 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<Object, Object> 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
  • 相关阅读:
    JavaScript和ASP.NET的传值
    访问webServices时遇到“测试窗体只能用于来自本地计算机的请求”的解决办法
    使用应用程序访问webservice功能
    利用应用程序访问webservice得到远程数据库数据并上传本地数据
    Win7 Wifi和安卓端连接
    Android项目运行junit测试类时出现错误Internal Error (classFileParser.cpp:3494)的解决办法
    安装Android开发工具及环境配置
    怎样修改注册表,让程序开机自动运行[收藏]
    怎么卸载Apache_pn服务PHPnow使用问题
    【转】mssql中大小写的区分
  • 原文地址:https://www.cnblogs.com/weiqihome/p/11939180.html
Copyright © 2011-2022 走看看