动态配置_动态配置文件 - CSDN
精华内容
参与话题
  • 动态配置

    2019-09-14 03:30:13
    动态配置用于当前控制器或者某个方法里面进行动态的改变设置 我们想只需要在当前控制器生效,需要一个构造方法,这里使用index.php <?php class Index { public function index() { dump(config()); } ...

    之前学习了整个应用配置和对模块的单独配置
    动态配置用于当前控制器或者某个方法里面进行动态的改变设置

    我们想只需要在当前控制器生效,需要一个构造方法,这里使用index.php

    <?php
    
    class Index
    {
        public function index()
        {
    		
    		dump(config());
        }
    		public function __construct(){
    			config('before','hhh123');
    		}
    }
    

    打开浏览器查看效果
    在这里插入图片描述

    如果当前方法配置了,只会在当前方法生效

    展开全文
  • 在微服务架构中,服务之间有着错综复杂的依赖关系,每个服务都有自己的依赖配置,在运行期间很多配置会根据访问...动态配置中心也是一个微服务,我们把微服务中需要动态配置的配置文件存放在远程git私有仓库上,微服...
    在微服务架构中,服务之间有着错综复杂的依赖关系,每个服务都有自己的依赖配置,在运行期间很多配置会根据访问流量等因素进行调整,传统的配置信息处理方式是将配置信息写入xml、.properties等配置文件中,和应用一起打包,每次修改配置信息,都需要重新进行打包,效率极低,动态配置中心就是为了解决这一问题。动态配置中心也是一个微服务,我们把微服务中需要动态配置的配置文件存放在远程git私有仓库上,微服务会去服务器读取配置信息,当我们在本地修改完代码push到git服务器,git服务器端hooks自动检测是否有配置文件更新,如果有,git服务端通过消息队列给配置中心发消息,通知配置中心刷新配置文件。因此微服务读取到的就是最新的配置信息,实现了运行期动态配置。理解了配置中心的原理,下面来介绍应用Spring Cloud框架的configserver搭建动态配置中心的整个过程。

           1、Git私有仓库搭建

           由于所有配置文件放在Git远程私有仓库上,我们需要搭建Git私有仓库。

           1)安装git

           # cd /etc/yum.repos.d/

           # wget http://geekery.altervista.org/geekery-el5-x86_64.repo

           # cd /data/soft/

           # wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

           # rpm -ivh rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm

           # yum -y install git

           # git --version

           2)搭建git仓库

           a、创建一个git用户,用来运行git服务

           命令:$ sudo adduser git

           b、创建证书登录

           收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥加入到/home/git/.ssh/authorized_keys文件里,一行一个。

           c、初始化git仓库

           选定或创建一个目录作为Git仓库,如/home/git/microservice.git,将此目录初始化为git仓库

             命令:$ sudo git init --bare microservice.git

     

                     $ sudo chown -R git:git microservice.git

           d、克隆远程仓库

           命令:$ git clone git@192.168.0.136:microservice.git

           3)在本地安装git客户端

           以上操作完成Git服务端私有仓库搭建后,需要在本地安装Git客户端,并且把公钥加入到服务端的/.ssh/authorized_keys配置文件中,这样就可以在本地克隆服务端代码并向服务端进行推送了。本地Git客户端的安装可参照Git教程。

           2、安装消息队列

           在远程机器上安装消息队列(rabbitmq)并启动

           

           3、配置中心相关配置文件

           配置中心(配置服务,例如:sample-config)的配置文件application.yml,添加如下配置:

           

           1)configserver的git配置

           configserver根据配置的Git服务器地址,去服务器上读取相应的配置文件信息。

           uri: 用户名、远程Git服务器地址、私有仓库地址

           username: Git服务器用户名(搭建仓库时创建的用户)

           password: 用户密码

           2)消息队列配置

           当Git服务端检测到配置文件有更新时,会通过消息队列通知configserver刷新配置文件。

           rabbitmq配置:

           host: 消息队列的地址

           port: 消息队列端口

           username: 用户名

           password: 密码 

           3)Dockerfile配置

           由于采用ssh协议访问Git服务器时,需要手动输入确认连接信息,因此在这里我们需要屏蔽此检查。我们需要新建一个配置文件config(无后缀名)跟Dockerfile一起放在容器中,并在Dockerfile中进行配置(新建/.ssh目录,将config文件添加到此目录下)。

           部署在容器中的文件:

           

           config文件配置:

           

           Dockerfile配置:

           

           4、在服务中添加消息总线依赖配置

           在需要将配置文件放到配置中心进行动态配置的服务中,添加消息总线的配置。

           在服务的pom.xml文件中添加依赖:

           <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-starter-bus-amqp</artifactId>

            </dependency>

           

           5、在Git服务端编写服务端hook

           当本地Git客户端向服务端仓库推送更新时,Git服务端需要检测配置文件是否有更新,如果有,则需要向configserver发请求通知它刷新配置文件。这就需要用到服务端hook。在Git服务端的/.git/hooks/目录下,创建post-receive文件(无后缀名),并添加相应的脚本,当Git客户端推送更新,服务端更新完文件后会自动执行此post-receive文件脚本。

            

           6、在本地Git客户端提交修改并推送到Git服务端

           在本地更新配置文件后,提交到本地Git仓库,然后将本地更新push到Git服务端。

           相关Git命令:

           $ git add xxx.xml xx.yml -------将修改的配置文件xxx.xml、xx.yml添加到暂存区

           $ git commit -m “xxxxxx”-----将暂存区文件提交到本地Git仓库

           $ git push origin master ------将本地更新推送到服务端

           以上就是利用configserver实现动态配置中心的整个过程,整个配置完成后就可以在本地修改配置文件push到Git服务器,我们的微服务就可以动态读取到最新的配置了。

    展开全文
  • Nacos实现动态配置

    千次阅读 2019-07-31 09:51:02
    Nacos实现动态配置先说我遇到的坑然后去网上搜了大神们的博客配置成功之后springboot启动的结果应该是有这两条的 先说我遇到的坑 上面配置的是yaml文件,然后启动栏输出的是去找nacos-config.properties 然后悲剧...

    先说我遇到的坑

    在这里插入图片描述
    -----------------在这里插入图片描述
    上面配置的是yaml文件,然后启动栏输出的是去找nacos-config.properties

    然后悲剧了,死活读不到,要么就是读到null。

    然后去网上搜了大神们的博客

    要将dataid写成nacos-config.yml
    在这里插入图片描述
    然后在springboot中的配置上加上spring.cloud.nacos.config.file-extension用来表示配置文件后缀为yml,默认的config文件格式是“properties”的
    在这里插入图片描述
    原因我把大神的结论贴出来:
    在这里插入图片描述
    这张图转载自:https://blog.csdn.net/zhaojiacan/article/details/89922165

    配置成功之后springboot启动的结果应该是有这两条的

    在这里插入图片描述
    在logo下面第一行和第二行

    展开全文
  • Dubbo-Dubbo 动态配置中心

    万次阅读 2019-07-14 15:50:43
    Dubbo 动态配置中心 一、参考文档 http://dubbo.apache.org/zh-cn/docs/user/configuration/config-center.html 三大中心指的:注册中心,元数据中心,配置中心。在 2.7 之前的版本,Dubbo 只配备了注册中心,主流...

    Dubbo 动态配置中心

    一、参考文档

    http://dubbo.apache.org/zh-cn/docs/user/configuration/config-center.html

    三大中心指的:注册中心,元数据中心,配置中心。
    在 2.7 之前的版本,Dubbo 只配备了注册中心,主流使用的注册中心为 zookeeper。新增加了元数据中心和配置中心,自然是为了解决对应的痛点,下面我们来详细阐释三大中心改造的原因。

    元数据改造

    元数据是什么?元数据定义为描述数据的数据,在服务治理中,例如服务接口名,重试次数,版本号等等都可以理解为元数据。在 2.7 之前,元数据一股脑丢在了注册中心之中,这造成了一系列的问题:
    推送量大 -> 存储数据量大 -> 网络传输量大 -> 延迟严重
    生产者端注册 30+ 参数,有接近一半是不需要作为注册中心进行传递;消费者端注册 25+ 参数,只有个别需要传递给注册中心。有了以上的理论分析,Dubbo 2.7 进行了大刀阔斧的改动,只将真正属于服务治理的数据发布到注册中心之中,大大降低了注册中心的负荷。
    同时,将全量的元数据发布到另外的组件中:元数据中心。元数据中心目前支持 redis(推荐),zookeeper。这也为 Dubbo 2.7 全新的 Dubbo Admin 做了准备,关于新版的 Dubbo Admin,我将会后续准备一篇独立的文章进行介绍。
    示例:使用 zookeeper 作为元数据中心
    <dubbo:metadata-report address=“zookeeper://127.0.0.1:2181”/>

    Dubbo 2.6 元数据

    dubbo://30.5.120.185:20880/com.alibaba.dubbo.demo.DemoService?
    anyhost=true&
    application=demo-provider&
    interface=com.alibaba.dubbo.demo.DemoService&
    methods=sayHello&
    bean.name=com.alibaba.dubbo.demo.DemoService&
    dubbo=2.0.2&
    executes=4500&
    generic=false&
    owner=kirito&
    pid=84228&
    retries=7&
    side=provider&
    timestamp=1552965771067
    从本地的 zookeeper 中取出一条服务数据,通过解码之后,可以看出,的确有很多参数是不必要。

    Dubbo 2.7 元数据

    在 2.7 中,如果不进行额外的配置,zookeeper 中的数据格式仍然会和 Dubbo 2.6 保持一致,这主要是为了保证兼容性,让 Dubbo 2.6 的客户端可以调用 Dubbo 2.7 的服务端。如果整体迁移到 2.7,则可以为注册中心开启简化配置的参数:
    <dubbo:registry address=“zookeeper://127.0.0.1:2181” simplified=“true”/>
    Dubbo 将会只上传那些必要的服务治理数据,一个简化过后的数据如下所示:
    dubbo://30.5.120.185:20880/org.apache.dubbo.demo.api.DemoService?
    application=demo-provider&
    dubbo=2.0.2&
    release=2.7.0&
    timestamp=1552975501873
    对于那些非必要的服务信息,仍然全量存储在元数据中心之中:

    元数据中心的数据可以被用于服务测试,服务 MOCK 等功能。目前注册中心配置中 simplified 的默认值为 false,因为考虑到了迁移的兼容问题,在后续迭代中,默认值将会改为 true。

    配置中心支持

    衡量配置中心的必要性往往从三个角度出发:

    1. 分布式配置统一管理
    2. 动态变更推送
    3. 安全性

    Spring Cloud Config, Apollo, Nacos 等分布式配置中心组件都对上述功能有不同程度的支持。在 2.7 之前的版本中,在 zookeeper 中设置了部分节点:configurators,routers,用于管理部分配置和路由信息,它们可以理解为 Dubbo 配置中心的雏形。在 2.7 中,Dubbo 正式支持了配置中心,目前支持的几种注册中心 Zookeeper,Apollo,Nacos(2.7.1-release 支持)。
    在 Dubbo 中,配置中心主要承担了两个作用

    • 外部化配置。启动配置的集中式存储
    • 服务治理。服务治理规则的存储与通知

    示例:使用 Zookeeper 作为配置中心
    <dubbo:config-center address=“zookeeper://127.0.0.1:2181”/>
    引入配置中心后,需要注意配置项的覆盖问题。

    二、动态配置中心

    何为配置中心?配置中心即就是我们平常经常见的比如注册中心的地址,服务的版本,服务的分组,反正在dubbo中能够看到的一些信息都可以作为配置中心中去存储。官方说的这两点比较的明确。就是一些外部化的参数配置,其实这个在其他的配置中心组件中非常常见,比如diamond 从remote获取配置信息,然后覆盖本地的信息。
    image.png

    1、直接下载官方demo工程

    git clone   https://github.com/apache/dubbo-samples.git
    

    dubbo-samples-zookeeper

    spring/dubbo-provider.properties
    将本地的配置修改为配置中心的地址

    dubbo.application.name=zookeeper-demo-provider
    dubbo.config-center.address=zookeeper://127.0.0.1:2181
    
    #dubbo.registry.address=zookeeper://${zookeeper.address:localhost}:2181
    #dubbo.protocol.name=dubbo
    #dubbo.protocol.port=20880
    #dubbo.application.qosEnable=true
    #dubbo.application.qosPort=33333
    dubbo.application.qosAcceptForeignIp=false
    
    
    

    2、配置管理

    Dubbo admin 配置中
    image.png
    将一些基础配置信息配置进去

    dubbo.registry.address=zookeeper://127.0.0.1:2181 
    dubbo.metadata-report.address=zookeeper://127.0.0.1:2181
    dubbo.protocol.name=dubbo
    dubbo.protocol.port=20880
    dubbo.application.qosEnable=true
    dubbo.application.qosPort=33333
    dubbo.application.qosAcceptForeignIp=false
    

    3、查看 zookeeper

    image.png

    4、启动demo服务即可。

    发现demo 发现日志监听配置的变化

    12/07/19 10:35:23:023 CST] main-EventThread  INFO state.ConnectionStateManager: State change: CONNECTED
    [12/07/19 10:35:23:023 CST] ZookeeperDynamicConfiguration-thread-1  INFO curator.CuratorZookeeperClient:  [DUBBO] listen the zookeeper changed. The changed data:ChildData{path='/dubbo/config', stat=427,427,1562936763476,1562936763476,0,1,0,0,0,1,428
    , data=[]}, dubbo version: 2.7.2, current host: 192.168.199.112
    [12/07/19 10:35:23:023 CST] ZookeeperDynamicConfiguration-thread-1  INFO curator.CuratorZookeeperClient:  [DUBBO] listen the zookeeper changed. The changed data:ChildData{path='/dubbo/config/dubbo', stat=428,428,1562936763478,1562936763478,0,1,0,0,0,1,429
    , data=[]}, dubbo version: 2.7.2, current host: 192.168.199.112
    [12/07/19 10:35:23:023 CST] ZookeeperDynamicConfiguration-thread-1  INFO curator.CuratorZookeeperClient:  [DUBBO] listen the zookeeper changed. The changed data:ChildData{path='/dubbo/config/dubbo/dubbo.properties', stat=429,465,1562936763479,1562940541881,4,0,0,0,267,0,429
    , data=[100, 117, 98, 98, 111, 46, 114, 101, 103, 105, 115, 116, 114, 121, 46, 97, 100, 100, 114, 101, 115, 115, 61, 122, 111, 111, 107, 101, 101, 112, 101, 114, 58, 47, 47, 49, 50, 55, 46, 48, 46, 48, 46, 49, 58, 50, 49, 56, 49, 32, 10, 100, 117, 98, 98, 111, 46, 109, 101, 116, 97, 100, 97, 116, 97, 45, 114, 101, 112, 111, 114, 116, 46, 97, 100, 100, 114, 101, 115, 115, 61, 122, 111, 111, 107, 101, 101, 112, 101, 114, 58, 47, 47, 49, 50, 55, 46, 48, 46, 48, 46, 49, 58, 50, 49, 56, 49, 10, 100, 117, 98, 98, 111, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 110, 97, 109, 101, 61, 100, 117, 98, 98, 111, 10, 100, 117, 98, 98, 111, 46, 112, 114, 111, 116, 111, 99, 111, 108, 46, 112, 111, 114, 116, 61, 50, 48, 56, 56, 48, 10, 100, 117, 98, 98, 111, 46, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 46, 113, 111, 115, 69, 110, 97, 98, 108, 101, 61, 116, 114, 117, 101, 10, 100, 117, 98, 98, 111, 46, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 46, 113, 111, 115, 80, 111, 114, 116, 61, 51, 51, 51, 51, 51, 10, 100, 117, 98, 98, 111, 46, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 46, 113, 111, 115, 65, 99, 99, 101, 112, 116, 70, 111, 114, 101, 105, 103, 110, 73, 112, 61, 102, 97, 108, 115, 101]}, dubbo version: 2.7.2, current host: 192.168.199.112
    [12/07/19 10:35:23:023 CST] ZookeeperDynamicConfiguration-thread-1  INFO curator.CuratorZookeeperClient:  [DUBBO] listen the zookeeper changed. The changed data:null, dubbo version: 2.7.2, current host: 192.168.199.112
    

    全局的额陪孩子和官方文档相同处理逻辑。
    image.png

    5、实现原理

    在这里插入图片描述

    三、源码解析

    1、服务导出

    监听到spring 启动完毕,然后服务进行导出
    org.apache.dubbo.config.spring.ServiceBean#onApplicationEvent
    org.apache.dubbo.config.spring.ServiceBean#export

     public void onApplicationEvent(ContextRefreshedEvent event) {
            if (!isExported() && !isUnexported()) {
                if (logger.isInfoEnabled()) {
                    logger.info("The service ready on spring started. service: " + getInterface());
                }
                export();
            }
        }
    

    org.apache.dubbo.config.ServiceConfig#export
    这里是同步的进行导出服务,先检查配置项信息。

    public synchronized void export() {
            checkAndUpdateSubConfigs();
    
            if (!shouldExport()) {
                return;
            }
    
            if (shouldDelay()) {
                delayExportExecutor.schedule(this::doExport, getDelay(), TimeUnit.MILLISECONDS);
            } else {
                doExport();
            }
        }
    

    2、获取配置流程

    org.apache.dubbo.config.ServiceConfig#checkAndUpdateSubConfigs

    1. 获取本地的全局配置,比如应用、注册中心、协议、配置中心地址等等
    2. 从配置中心获取信息
     public void checkAndUpdateSubConfigs() {
            // Use default configs defined explicitly on global configs
            completeCompoundConfigs();
            // Config Center should always being started first.
            startConfigCenter();
            checkDefault();
            checkProtocol();
            checkApplication();
            // if protocol is not injvm checkRegistry
            if (!isOnlyInJvm()) {
                checkRegistry();
            }
            this.refresh();
            checkMetadataReport();
    
            if (StringUtils.isEmpty(interfaceName)) {
                throw new IllegalStateException("<dubbo:service interface=\"\" /> interface not allow null!");
            }
    
            if (ref instanceof GenericService) {
                interfaceClass = GenericService.class;
                if (StringUtils.isEmpty(generic)) {
                    generic = Boolean.TRUE.toString();
                }
            } else {
                try {
                    interfaceClass = Class.forName(interfaceName, true, Thread.currentThread()
                            .getContextClassLoader());
                } catch (ClassNotFoundException e) {
                    throw new IllegalStateException(e.getMessage(), e);
                }
                checkInterfaceAndMethods(interfaceClass, methods);
                checkRef();
                generic = Boolean.FALSE.toString();
            }
            if (local != null) {
                if ("true".equals(local)) {
                    local = interfaceName + "Local";
                }
                Class<?> localClass;
                try {
                    localClass = ClassUtils.forNameWithThreadContextClassLoader(local);
                } catch (ClassNotFoundException e) {
                    throw new IllegalStateException(e.getMessage(), e);
                }
                if (!interfaceClass.isAssignableFrom(localClass)) {
                    throw new IllegalStateException("The local implementation class " + localClass.getName() + " not implement interface " + interfaceName);
                }
            }
            if (stub != null) {
                if ("true".equals(stub)) {
                    stub = interfaceName + "Stub";
                }
                Class<?> stubClass;
                try {
                    stubClass = ClassUtils.forNameWithThreadContextClassLoader(stub);
                } catch (ClassNotFoundException e) {
                    throw new IllegalStateException(e.getMessage(), e);
                }
                if (!interfaceClass.isAssignableFrom(stubClass)) {
                    throw new IllegalStateException("The stub implementation class " + stubClass.getName() + " not implement interface " + interfaceName);
                }
            }
            checkStubAndLocal(interfaceClass);
            checkMock(interfaceClass);
        }
    

    3、获取全局配置信息

    org.apache.dubbo.config.ServiceConfig#completeCompoundConfigs

    private void completeCompoundConfigs() {
            if (provider != null) {
                if (application == null) {
                    setApplication(provider.getApplication());
                }
                if (module == null) {
                    setModule(provider.getModule());
                }
                if (registries == null) {
                    setRegistries(provider.getRegistries());
                }
                if (monitor == null) {
                    setMonitor(provider.getMonitor());
                }
                if (protocols == null) {
                    setProtocols(provider.getProtocols());
                }
                if (configCenter == null) {
                    setConfigCenter(provider.getConfigCenter());
                }
            }
            if (module != null) {
                if (registries == null) {
                    setRegistries(module.getRegistries());
                }
                if (monitor == null) {
                    setMonitor(module.getMonitor());
                }
            }
            if (application != null) {
                if (registries == null) {
                    setRegistries(application.getRegistries());
                }
                if (monitor == null) {
                    setMonitor(application.getMonitor());
                }
            }
    

    3、获取配置中心

    org.apache.dubbo.config.AbstractInterfaceConfig#startConfigCenter
    环境信息准备是重点。

     void startConfigCenter() {
           ## 配置中心配置是否存在
            if (configCenter == null) {
                ConfigManager.getInstance().getConfigCenter().ifPresent(cc -> this.configCenter = cc);
            }
    
            if (this.configCenter != null) {
                // TODO there may have duplicate refresh
                this.configCenter.refresh();
                ## 准备获环境信息
                prepareEnvironment();
            }
            ConfigManager.getInstance().refreshAll();
        }
    

    4、环境信息准备

    org.apache.dubbo.config.AbstractInterfaceConfig#prepareEnvironment
    image.png

    动态获取配置中心的实现,然后获取到全局配置内容,获取应用配置内容,然后刷新到本地的环境变量中去。

    private void prepareEnvironment() {
            if (configCenter.isValid()) {
                if (!configCenter.checkOrUpdateInited()) {
                    return;
                }
                ## 获取配置中心实现类
                DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());
                
                ## 获取常量
                String configContent = dynamicConfiguration.getConfigs(configCenter.getConfigFile(), configCenter.getGroup());
    
                String appGroup = application != null ? application.getName() : null;
                String appConfigContent = null;
                if (StringUtils.isNotEmpty(appGroup)) {
                    appConfigContent = dynamicConfiguration.getConfigs
                            (StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                             appGroup
                            );
                }
                try {
                    Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
                    Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
                    Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
                } catch (IOException e) {
                    throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
                }
            }
        }
    

    5、SPI 动态获取配置工厂

    org.apache.dubbo.config.AbstractInterfaceConfig#getDynamicConfiguration

    
        private DynamicConfiguration getDynamicConfiguration(URL url) {
            DynamicConfigurationFactory factories = ExtensionLoader
                    .getExtensionLoader(DynamicConfigurationFactory.class)
                    .getExtension(url.getProtocol());
            DynamicConfiguration configuration = factories.getDynamicConfiguration(url);
            Environment.getInstance().setDynamicConfiguration(configuration);
            return configuration;
        }
    
    

    image.png

    6、ZookeeperDynamicConfigurationFactory 工厂的实现

    org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory
    给予了注册的地址
    image.png

    public class ZookeeperDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
    
        private ZookeeperTransporter zookeeperTransporter;
    
        public void setZookeeperTransporter(ZookeeperTransporter zookeeperTransporter) {
            this.zookeeperTransporter = zookeeperTransporter;
        }
    
    
        @Override
        protected DynamicConfiguration createDynamicConfiguration(URL url) {
            return new ZookeeperDynamicConfiguration(url, zookeeperTransporter);
        }
    }
    

    7、 ZookeeperDynamicConfiguration连接

    org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration#ZookeeperDynamicConfiguration
    这里监听的路径启动

    ZookeeperDynamicConfiguration(URL url, ZookeeperTransporter zookeeperTransporter) {
            this.url = url;
            rootPath = "/" + url.getParameter(CONFIG_NAMESPACE_KEY, DEFAULT_GROUP) + "/config";
    
            initializedLatch = new CountDownLatch(1);
            this.cacheListener = new CacheListener(rootPath, initializedLatch);
            this.executor = Executors.newFixedThreadPool(1, new NamedThreadFactory(this.getClass().getSimpleName(), true));
    
            zkClient = zookeeperTransporter.connect(url);
            zkClient.addDataListener(rootPath, cacheListener, executor);
            try {
                // Wait for connection
                this.initializedLatch.await();
            } catch (InterruptedException e) {
                logger.warn("Failed to build local cache for config center (zookeeper)." + url);
            }
        }
    

    8、环境信息准备–>获取到配置信息

    org.apache.dubbo.config.AbstractInterfaceConfig#prepareEnvironment
    配置文件、分组都是URL中的参数

     private void prepareEnvironment() {
            if (configCenter.isValid()) {
                if (!configCenter.checkOrUpdateInited()) {
                    return;
                }
                DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());
                String configContent = dynamicConfiguration.getConfigs(configCenter.getConfigFile(), configCenter.getGroup());
    
                String appGroup = application != null ? application.getName() : null;
                String appConfigContent = null;
                if (StringUtils.isNotEmpty(appGroup)) {
                    appConfigContent = dynamicConfiguration.getConfigs
                            (StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
                             appGroup
                            );
                }
                try {
                    Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
                    Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
                    Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
                } catch (IOException e) {
                    throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
                }
            }
        }
    
    

    9 读取配置文件

    org.apache.dubbo.common.config.ConfigurationUtils#parseProperties

    public static Map<String, String> parseProperties(String content) throws IOException {
            Map<String, String> map = new HashMap<>();
            if (StringUtils.isEmpty(content)) {
                logger.warn("You specified the config centre, but there's not even one single config item in it.");
            } else {
                Properties properties = new Properties();
                properties.load(new StringReader(content));
                properties.stringPropertyNames().forEach(
                        k -> map.put(k, properties.getProperty(k))
                );
            }
            return map;
        }
    

    整个流程结束.

    四、总结

    整个源码的分析可以看出,整个流程链路比较的清爽、功能划分比较清楚,什么时候该干什么,学习了一波。

    展开全文
  • 首先我们先建立一个配置中心: 1先建立一个module命名为cloud-config-center-3344,然后先来看下目录 2导入pom依赖 依赖:主要依赖spring-cloud-config-server <?xml version="1.0" encoding="UTF-8"?> <...
  • (一)Nacos动态配置(二)Nacos注册中心(三)Sentinel之限流(四)Sentinel之熔断(五)Gateway之路由、限流(六)Gateway之鉴权、日志(七)Gateway搭配Nacos实现动态路由(八)Dubbo + Nacos 正文 前两年的Spring微服务世界,...
  • 最近在做springcloud的集群构建,在业务代码层,遇到了动态配置,当然可以采用springcloud的config的配置中心,但是感觉这个配置在使用上极度不爽,因为我不仅仅要构建一版开发环境的,还需要我手动的将配置文件上传...
  • springboot整合Quartz实现动态配置定时任务

    万次阅读 多人点赞 2017-08-03 10:32:53
    在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置,下面就通过一个简单的示例,来实现这个功能。 一、新建一个springboot工程,并添加依赖 org.spring...
  • 配置两个环境的,可根据实际需要增加环境模式(开发环境dev,测试环境test,回归坏境retu,预生产环境pre,生产环境prod,等等) dev代表开发环境: prod代表生产环境 pom.xml里面配置profiles: <...
  • zuul动态配置路由规则,从DB读取

    万次阅读 热门讨论 2017-10-12 13:37:00
    zuul作为一个网关,是用户请求的入口,担当鉴权、转发的重任,理应保持高可用性和具备动态配置的能力。我画了一个实际中可能使用的配置框架,如图。当用户发起请求后,首先通过并发能力强、能承担更多用户请求的负载...
  • Spring Cloud Zuul路由动态配置

    千次阅读 2019-02-02 19:28:23
    Spring Cloud Zuul动态路由配置Zuul配置在mysql中创建路由信息表,对于类如下:定义CustomRouteLocator类增加CustomZuulConfig类,主要是为了配置CustomRouteLocatorRefreshRouteService类,用于实现数据库路由信息...
  • 1 springboot之动态配置定时任务

    万次阅读 2018-01-16 17:49:32
    最近项目中有关于springboot中动态配置定时任务的需求,查阅各种资料,最终实现了可以动态的开关定时器,以及配置定时器的时间节点。 网上有很多关于springboot定时任务的介绍,之前项目中也用过quartz,和...
  • nginx动态配置配置

    千次阅读 2019-01-04 16:17:22
    nginx中的conf文件配置测试 upstream backServer{ server 127.0.0.1:11111; upsync 192.168.212.134:8500/v1/kv/upstreams/itmayiedu upsync_timeout=6m upsync_interval=500ms upsync_type=consul strong...
  • 概念 在Nacos中,本身有多个不同管理级别的概念,包括:Data ID、...Data ID在Nacos中,我们可以理解为就是一个Spring Cloud应用的配置文件名,我们知道默认情况下Data ID的名称格式是这样的:${spring.applicat...
  • Hystrix系列-4-Hystrix的动态配置

    千次阅读 2017-06-25 16:31:56
    Hystrix默认使用Archaius来实现的动态配置,我们在上节中,使用了代码的方式来实现配置,这节,我们使用Hystrix的动态配置来实现。 1、实现一个Command,代码如下: package com.example.demo.hystrix.command; ...
  • Spring 的参数动态配置

    千次阅读 2016-07-15 16:13:56
    有时候需要从properties文件中加载配置,以前的方式是这样的: [html] view plain copy bean id="jdbcProperties" class="org.springframework.beans.factory.config....
  • logback 动态配置 写在前面 在做java日志之前,强烈建议大家读一下这篇java日志的前世今生,对理清java日志框架很有帮助! 奉上地址: 一个著名的日志系统是怎么设计出来的 然后说一下,为啥要使用动态日志...
  • spring schedule 动态配置执行时间

    千次阅读 2019-01-23 09:46:49
    但是最近给银行做的一个小项目,需要本地化部署,所以我不想弄很多的服务,并且他们并没有要求修改以后即时生效,所以我直接采用了 spring schedule结合mysql动态配置执行时间。 之前我们用的schedule通过注解的...
  • Quartz实现JAVA定时任务的动态配置

    千次阅读 2019-05-27 17:47:26
    什么是动态配置定时任务? 首先说下这次主题,动态配置。没接触过定时任务的同学可以先看下此篇:JAVA定时任务实现的几种方式 定时任务实现方式千人千种,不过基础的无外乎 1、JDK 的Timer类 2、Quartz 3、Spring...
  • dubbo 动态配置

    千次阅读 2018-09-28 10:27:03
    RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(URL.valueOf("...
1 2 3 4 5 ... 20
收藏数 1,016,193
精华内容 406,477
关键字:

动态配置