使用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

原文地址:https://www.cnblogs.com/weiqihome/p/11939180.html

时间: 2024-08-15 04:17:10

使用Apollo动态修改线上数据源的相关文章

fiddler修改线上的内容

有时候本地的代码跟线上的代码还是运行环境还是有区别的.比如有些封装的方法需要运动到手机上可以调试,而浏览器是无法调试的.如果不想每次修改完再放上到测试环境看效果,那要怎么做呢?fiddler为我们提供了很多的便利,直接就可以让你通过本地的代码,来让线上马上就可以访问到.来来来,走起 操作如下:(图片发布到线上变形了,抱歉,不过基本可以看懂) 第一步:打开你需要替换的内容网站,找到你要替换的内容 比如我想替换博客园右边栏的那张广告图片,不错,我就是看不惯这个广告,所以我想把这个图给换掉.你可以在谷

log4j2和logback动态修改日志级别工具类

工作中,有些场景需要动态修改线上日志记录器的打印日志级别, 本文的两个工具类使用的版本如下: ----------------logback--------------------- <dependency>   <groupId>ch.qos.logback</groupId>   <artifactId>logback-core</artifactId>   <version>1.1.8</version></d

chrome浏览器调试线上文件映射本地文件

通过ReRes让chrome拥有路径映射的autoResponse功能. 前端开发过程中,经常会有需要对远程环境调试的需求.比如,修改线上bug,开发环境不在本地等等.我们需要把远程css文件或者js映射到本地的文件上,通过修改本地文件进行调试和开发.通常我们可以通过以下方法来实现映射: 1.修改host文件——只能把域名映射到IP 2.使用Apache或者nginx搭建反向代理——需要装环境,配置相对繁琐 3.使用Fiddler中的AutoRespnose功能——不支持目录映射,mac.lin

动态修改JDBC数据源配置

因项目需要能动态修改数据源的配置,及修改后不用重启整个应用.使用的数据源是apache的BasicDataSource,网上千篇一律的是如下实现: BasicDataSource bds=getDataSource();  try{   bds.close();     }  catch(Exception e){   e.printStackTrace();  }  bds.setUsername("sa");  bds.setPassword("admin");

线上修改redis内存分配大小

VM:/data/bak # telnet 192.168.1.1 12403 Trying 192.168.1.1... Connected to 192.168.1.1. Escape character is '^]'. config get maxmemory       //查看 *2 $9 maxmemory $10 1000000000                 //当前为1G config set maxmemory 2000000000   //  设置为2G CTRL+

集算报表用Java动态修改报表数据源

实际应用中通过程序动态修改报表模板的情况很常见,其中动态修改数据源SQL就是一种典型场景.常见于系统中有一些结构相同而数据源不同的报表,为减少报表开发工作量,只开发一套报表模板,使用时通过程序动态修改数据源来满足实际需要. 下面通过一个使用JAVA程序修改集算报表数据源SQL的例子说明使用过程. 编辑报表模板: 由于不同数据源的字段不同,因此这里使用动态表达式ds1.fname()获取字段名,ds1.field()获取字段值.此外,第一行和第一列为辅助行列,设置其隐藏. 编写代码: 1.读入报表

Django线上部署代码修改失效问题

记一次django项目的线上部署维护问题,django+nginx 关于nginx反向代理服务器的介绍这里有一篇博客介绍的比较好:nginx的相关介绍 以及当一次客户端请求发出后,uwsig以及uWSGI,Nginx之间的大致流程:uWSGI.WSGI和uwsgi 一.问题描述 在将django项目部署到阿里云(nginx作为web服务器)上之后,使用宝塔控制面板修改项目源码,或者使用直接在终端修改,修改之后重启uwsgi和nginx无效. 二.问题分析 1.本地环境 在本地环境的时候,是使用D

nginx之线上CDN的rewrite规则修改

线上的CDN厂商的nginx的rewrite规则配置验证 验证测试:为使nginx vhost虚拟主机配置文件更简洁,所以采用include方式,把nginx的rewrite规则写到一个单独的配置文件中 [[email protected] vhost]# grep include /usr/local/nginx/conf/vhost/img.test.conf include /data/www/images/.htaccess; 下面的rewrite规则是云端CDN的提供的配置规则,但是其

配置开发环境测试环境线上生产环境

1.正确打包 项目有三种环境: 1.本地开发环境(local) 2.开发测试环境(dev) 3.线上生产环境(product) 不同的环境有不同的配置,比如数据库连接什么的....maven打包时默认去resources文件夹下打包这些配置文件,放在WEB-INF/classes下,然后再打成war包,就能用了...现在通过修改pom.xml文件,增加三种配置,让maven打包时选择打包不同文件夹下的配置文件到WEB-INF/classes下,这样就省事儿了.... 如图所示,resources