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

  期初的想法是有没有办法将配置文件与系统隔离开来,这样在更新时候,就只需要更新代码部分,配置文件不用去管了。查了不少资料,没找到什么好的实现方式,别人比较好的发布框架都是自己写的,也用了,干脆自己研究研究能不能使用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. 一份快速完整的Tensorflow模型保存和恢复教程(译)(转载)

    该文章转自https://blog.csdn.net/sinat_34474705/article/details/78995196 我在进行图像识别使用ckpt文件预测的时候,这个文章给我提供了极大 ...

  2. Idea中运行项目时出现:未结束的字符串解决方案

    一般出现这种情况是编码不一致导致 解决办法: settings>file Encodings 编码设置成一致

  3. html2canvas html截图插件

    以下我总结了一些注意事项,在代码中注释了,仅供参考. html2canvas.js点击付:完整使用的demo ,如下: <!DOCTYPE html><html lang=" ...

  4. Balls(扔鸡蛋问题)

    4554 BallsThe classic Two Glass Balls brain-teaser is often posed as:“Given two identical glass sphe ...

  5. jQuery formValidator API

    jQuery formValidator插件的API帮助 目前支持5种大的校验方式,分别是:inputValidator(针对input.textarea.select控件的字符长度.值范围.选择个数 ...

  6. Java学习08 (第一遍) - SpringMVC

    写一下午的好多居然丢失...自动保存也只是保存丢失后的 那就不多写了,简单写: Spring:(自己画的) 官网的: 写一个Spring的例子: Eclipse http://repo.spring. ...

  7. vue浏览器滚动加载更多

    created () { var that = this; window.addEventListener('scroll',this.scroll,true) console.log(this.$r ...

  8. psdTohtml

    https://github.com/anjorweb/fastHtml fastHtml 一个简单的psd直接导出html的工具 自己工作常用整理 适合单页面且采用DOM结构布局的H5页面,基于Ca ...

  9. datatables插件提示Cannot reinitialise DataTable的解决办法

    这个错误是由于重新设置数据源,又没有将原来的数据清空导致的. 网上有很多解决方案,试了都不管用. 最后找到一种方法,将原来的table销毁,再初始化. 方法是在datatable初始化的时候加入属性 ...

  10. 大数据入门到精通7--对复合value做reducebykey

    培训系列7--对复合value做reduce 1.做基础数据准备 val collegesRdd= sc.textFile("/user/hdfs/CollegeNavigator.csv& ...