最近频繁的系统上线,每次打包都要把配置文件替换为正式环境的配置文件,虽然说就是复制粘贴的事,架不住文件杂乱,而且多。

  期初的想法是有没有办法将配置文件与系统隔离开来,这样在更新时候,就只需要更新代码部分,配置文件不用去管了。查了不少资料,没找到什么好的实现方式,别人比较好的发布框架都是自己写的,也用了,干脆自己研究研究能不能使用zk做一个配置文件的管理中心,顺带实现动态加载配置文件而不需要重启系统(正式环境这种情况使用的应该很少,不过本地倒是用起来顺手很多)。

  

  1,在虚拟机上安装zk(需先安装jdk):下载tar文件,解压,修改 cp zoo_sample.cfg zoo.cfg,

  • tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

  进入到bin目录下,sh zkServer.sh start

  进入zk客户端   sh zkCli.sh -server localhost:2181

  创建文件  create /fileName value

  2.java端引入zk客户端

  1).maven

   <!-- ZooKeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.9.0</version>
</dependency>
<!-- Zookeeper -->

  2).zookeeper.properties  

    zk.servers=192.168.3.252:2181
    zk.config.root.path=/conf

  3.我们在使用配置文件的时候,都是使用spring来托管,在项目启动的时候就加载到项目中去,zk有三种监听方式,为能够同时监听主目录及子目录的实时变化,选用TreeCacheListener。zk能够直接从服务端获取对应目录下的数据,并能够实时监听对应节点的变化以及变化之后的值,这里首先在项目启动加载配置文件的时候,用服务端的数据去覆盖项目中的数据,这样保证服务端有配置时以服务端为准,没有时则以项目中配置运行,然后实时监听对应节点,只要有服务端配置被修改,则覆盖项目中的原有配置,并刷新容器,使用最新的配置。

  核心代码:继承spring PropertyPlaceholderConfigurer 重写processProperties方法加载配置文件

  

@Override
protected void processProperties(ConfigurableListableBeanFactory beanFactory, Properties props) throws BeansException { InputStream in = ZooKeeperService.class.getClassLoader().getResourceAsStream("zookeeper.properties");
Properties pro = new Properties();
try{
pro.load(in);
}catch(Exception e){
logger.debug("zookeeper.properties读取错误!"+e.getMessage());
} this.zookeeperServers = pro.getProperty("zk.servers");
PATH = pro.getProperty("zk.config.root.path"); RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIMEMS, MAX_RETRIES);
this.client = CuratorFrameworkFactory.builder().connectString(this.zookeeperServers).retryPolicy(retryPolicy).build();
client.start(); @SuppressWarnings("resource")
TreeCache cache = new TreeCache(this.client, PATH);
try {
cache.start(); TreeCacheListener listener = new TreeCacheListener() { @Override
public void childEvent(CuratorFramework client, TreeCacheEvent event)
throws Exception {
if(null != event && null != event.getData()){
logger.debug(event.getData().getPath().toString()+":"
+new String(event.getData().getData())); String[] arr = event.getData().getPath().toString().split("/");
String key = arr[arr.length-1];
String value = new String(event.getData().getData());
proMap.putAll(updateConf(key,value)); }
}
}; cache.getListenable().addListener(listener); } catch (Exception e) {
logger.debug(e.getMessage());
} try {
        //加载顺序问题,因为是一个监听的过程,所以没办法顺序执行,测试时这里直接使用了延时来保证先获取到服务端的数据然后在加载参数,没有想到其他好的方法解决,在尝试使用CountDownLatch来解决,后续修改
            Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
props.putAll(proMap);
super.processProperties(beanFactory, props);
}

  基本实现如此。待完善。

maven 插件方式拆分开发,测试,正式环境配置文件

  resources 文件夹下 创建 dev(开发) qa(测试) pre(预生产) prod(生产) 几个文件夹 并且把对应的配置丢到(公用的不用丢)对应的文件夹

修改pom.xml
在dependencies 下面增加
<!--定义不同的环境变量-->
  <profiles>
    <profile>
      <!--开发-->
      <id>dev</id>
      <properties>
        <env>dev</env>
      </properties>
    </profile>
    <profile>
      <!--测试-->
      <id>qa</id>
      <properties>
        <env>qa</env>
      </properties>
  <!--默认是测试,额外加参数可修改此项,例如: mvn clean package -Pdev 表示打包时使用开发环境-->
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
    </profile>
    <profile>
  <!--预生产-->
      <id>pre</id>
      <properties>
        <env>pre</env>
      </properties>
    </profile>
    <profile>
      <!--生产-->
      <id>prod</id>
      <properties>
        <env>prod</env>
      </properties>
    </profile>
  </profiles>

build 节点下增加
  <!-- 控制 复制到target\classes文件夹的资源 的情况 -->
  <resources>
  <!-- 资源根目录排除各环境的配置,使用单独的资源目录来指定,这一步复制公共的配置 -->
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
      <excludes>
        <exclude>dev/*</exclude>
        <exclude>qa/*</exclude>
        <exclude>pre/*</exclude>
        <exclude>prod/*</exclude>
      </excludes>
    </resource>
  <!-- 这一步复制指定环境的配置 -->
    <resource>
    <directory>src/main/resources/${env}</directory>
    </resource>
  </resources>

搞定

maven插件会自动将对应的配置文件build进去,避免每次修改配置文件

  

zookeeper配置文件共享中心的更多相关文章

  1. zookeeper配置中心实战--solrcloud zookeeper配置中心原理及源码分析

    程序的发展,需要引入集中配置: 随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关.参数的配置.服务器的地址…… 并且对配置的期望也越来越高,配置修改后实时生效,灰度发布,分环境.分集群管理配 ...

  2. Dubbo原理解析-注册中心之Zookeeper协议注册中心

    下面我们来看下开源dubbo推荐的业界成熟的zookeeper做为注册中心, zookeeper是hadoop的一个子项目是分布式系统的可靠协调者,他提供了配置维护,名字服务,分布式同步等服务.对于z ...

  3. springboot整合dubbo\zookeeper做注册中心

    springboot整合dubbo发布服务,zookeeper做注册中心.前期的安装zookeeper以及启动zookeeper集群就不说了. dubbo-admin-2.5.4.war:dubbo服 ...

  4. 以zookeeper为注册中心搭建spring cloud环境

    在spring cloud体系中,有多种手段实现注册中心,本例中采用zookeeper作为注册中心的角色.服务提供者向zookeeper注册,服务消费者从zookeeper中发现服务提供者的相关信息, ...

  5. Dubbo框架应用之(三)--Zookeeper注冊中心、管理控制台的安装及解说

    我是在linux下使用dubbo-2.3.3以上版本号的zookeeper注冊中心客户端. Zookeeper是Apache Hadoop的子项目,强度相对较好,建议生产环境使用该注冊中心. Dubb ...

  6. Zookeeper用作注册中心的原理

    RPC框架中有3个重要的角色: 注册中心 :保存所有服务的名字,服务提供者的ip列表,服务消费者的IP列表: 服务提供者: 提供跨进程服务: 服务消费者: 寻找到指定命名的服务并消费. 一:Zooke ...

  7. Dubbo配置注册中心设置application的name使用驼峰命名法存在的隐藏项目启动异常问题

    原创/朱季谦 首先,先提一个建议,在SpringBoot+Dubbo项目中,Dubbo配置注册中心设置的application命名name的值,最好使用xxx-xxx-xxx这样格式的,避免随便使用驼 ...

  8. Java开发机器上的配置及zookeeper配置

    Java开发机器上的配置及zookeeper配置 /etc/profile 文件的后面加入下面的内容: # jdk, zookeeper, kafka, ant, maven export APACH ...

  9. 新装kafka与zookeeper配置

    zookeeper配置 dataDir=/opt/kafka_2.11-2.0.0/data/zookeeper # 尽量不要放在tmp# the port at which the clients ...

随机推荐

  1. 1816647 - Error "Data file of SAP Note is incomplete" uploading a note in SNOTE

    ymptom When uploading an SAP Note in transaction SNOTE you receive the error "Data file of SAP ...

  2. easy ui 关闭选项卡

    var tab = window.parent.getCurrentTab(); var tabs = window.parent.getTabs(); var index = tabs.tabs(& ...

  3. Spring MVC @SessionAttributes注解

    @SessionAttributes原理 默认情况下Spring MVC将模型中的数据存储到request域中.当一个请求结束后,数据就失效了.如果要跨页面使用.那么需要使用到session.而@Se ...

  4. kettle实现多表同步

    本样例实现源库的所有表到目标库的同步sqlserver=>mysql(目标表存在表结构则同步),总调度如下: 由于复制记录到结果保存了多个表名,存在多个值,在高级选择对每个输入行执行一次进行循环 ...

  5. TTS

    CLASS_SpVoice: TGUID = '{96749377-3391-11D2-9EE3-00C04F797396}'; http://blog.sina.com.cn/s/blog_4fce ...

  6. 关于HashMap和HashTable.md

    目录 先来些简单的问题 你用过HashMap吗?" "什么是HashMap?你为什么用到它?" "你知道HashMap的工作原理吗?" "你 ...

  7. hello1以及hello2的部分代码分析

    (一)1.GreetingServlet.java源码文件: @WebServlet("/greeting") //以@WebServlet注释开头,注释指定相对于上下文根的URL ...

  8. yum方面的知识

    修改CentOS默认yum源为国内yum镜像源 1.mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bac ...

  9. Chrome浏览器 调试工具 vue-devtools 的安装和使用

    https://www.cnblogs.com/yuqing6/p/7440549.html

  10. 688. Knight Probability in Chessboard棋子留在棋盘上的概率

    [抄题]: On an NxN chessboard, a knight starts at the r-th row and c-th column and attempts to make exa ...