博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ZooKeeper学习笔记—配置管理
阅读量:5954 次
发布时间:2019-06-19

本文共 6359 字,大约阅读时间需要 21 分钟。

  hot3.png

   最近在工作中,为了完善公司集群服务的架构,提高可用性,降低运维成本,因此开始学习ZooKeeper。

    至于什么是ZooKeeper?它能做什么?如何安装ZooKeeper?我就不一一介绍了,类似这些资料网上到处都是。我主要是把在开发过程中,以及个人对ZooKeeper的一些了解记录下来,大家如果遇到类似场景时,希望我的文章能够给你提供一些思路。
    我使用的ZooKeeper(以下简称:ZK)客户端是Curator Framework,是Apache的项目,它主要的功能是为ZK的客户端使用提供了高可用的封装。在Curator Framework基础上封装的curator-recipes,实现了很多经典场景。比如:集群管理(Leader选举)、共享锁、队列、Counter等等。可以总结Curator主要解决以下三类问题:

  • 封装ZK Client与Server之间的连接处理; 
  • 提供了一套Fluent风格的操作API; 
  • 提供ZK各种应用场景的抽象封装;

 

   本文主要完成的目标是:Spring PropertyPlaceholderConfigurer配置文件加载器集成ZooKeeper来实现远程配置读取。

    配置管理(Configuration Management)。

    在集群服务中,可能都会遇到一个问题:那就是当需要修改配置的时候,必须要对每个实例都进行修改,这是一个很繁琐的事情,并且易出错。当然可以使用脚本来解决,但这不是最好的解决办法。
 

OK,Let's go!

我们先看看项目结构

 

 

ZooKeeperPropertyPlaceholderConfigurer.java

继承org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,重写processProperties(beanFactoryToProcess, props)来完成远端配置加载的实现

package org.bigmouth.common.zookeeper.config.spring; import java.io.UnsupportedEncodingException;import java.util.Properties; import org.apache.commons.lang.StringUtils;import org.bigmouth.common.zookeeper.config.Config;import org.bigmouth.common.zookeeper.config.ZooKeeperConfig;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;  public class ZooKeeperPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {         public static final String PATH = "zoo.paths";     @Override    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)            throws BeansException {        super.processProperties(beanFactoryToProcess, props);                 try {            fillCustomProperties(props);                         System.out.println(props);        }        catch (Exception e) {            // Ignore            e.printStackTrace();        }    }     private void fillCustomProperties(Properties props) throws Exception {        byte[] data = getData(props);        fillProperties(props, data);    }     private void fillProperties(Properties props, byte[] data) throws UnsupportedEncodingException {        String cfg = new String(data, "UTF-8");        if (StringUtils.isNotBlank(cfg)) {            // 完整的应该还需要处理:多条配置、value中包含=、忽略#号开头            String[] cfgItem = StringUtils.split(cfg, "=");            props.put(cfgItem[0], cfgItem[1]);        }    }     private byte[] getData(Properties props) throws Exception {        String path = props.getProperty(PATH);        Config config = new ZooKeeperConfig();        return config.getConfig(path);    } }

Config.java

配置操作接口 

package org.bigmouth.common.zookeeper.config;  public interface Config {     byte[] getConfig(String path) throws Exception;}

Startup.java

程序启动入口

package org.bigmouth.common.zookeeper.config; import org.springframework.context.support.ClassPathXmlApplicationContext;  public class Startup {     public static void main(String[] args) {        new ClassPathXmlApplicationContext("classpath:/config/applicationContext.xml");    } }

ZooKeeperConfig.java

配置操作接口ZooKeeper的实现

package org.bigmouth.common.zookeeper.config; import org.apache.curator.framework.CuratorFramework;import org.apache.zookeeper.data.Stat;  public class ZooKeeperConfig implements Config {     @Override    public byte[] getConfig(String path) throws Exception {        CuratorFramework client = ZooKeeperFactory.get();        if (!exists(client, path)) {            throw new RuntimeException("Path " + path + " does not exists.");        }        return client.getData().forPath(path);    }         private boolean exists(CuratorFramework client, String path) throws Exception {        Stat stat = client.checkExists().forPath(path);        return !(stat == null);    } }

ZooKeeperFactory.java

管理ZooKeeper客户端连接

package org.bigmouth.common.zookeeper.config; import org.apache.curator.RetryPolicy;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.retry.ExponentialBackoffRetry; public class ZooKeeperFactory {     public static final String CONNECT_STRING = "172.16.3.42:2181,172.16.3.65:2181,172.16.3.24:2181";         public static final int MAX_RETRIES = 3;     public static final int BASE_SLEEP_TIMEMS = 3000;     public static final String NAME_SPACE = "cfg";     public static CuratorFramework get() {        RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIMEMS, MAX_RETRIES);        CuratorFramework client = CuratorFrameworkFactory.builder()                .connectString(CONNECT_STRING)                .retryPolicy(retryPolicy)                .namespace(NAME_SPACE)                .build();        client.start();        return client;    }}

applicationContext.xml

配置加载器使用我们自己创建的ZooKeeperPropertyPlaceholderConfigurer,因为它重写了processProperties方法。这个方法里会去读取远程配置。

classpath:application.properties

application.properties

项目配置文件,里面除了配置ZooKeeper服务器地址和读取的节点以外,其他所有的配置都应该保存在ZooKeeper中。

zoo.paths=/properties

设置ZooKeeper数据

登录ZooKeeper中为节点 /cfg/properties 添加一条配置项:

如图所示:我创建了一个节点 /cfg/properties 并设置内容为:jdbc.driver=org.postgresql.Driver

运行Startup.java

OK 了,zoo.paths是本地application.properties文件中的,jdbc.driver是远程ZooKeeper服务器中的。

项目中需要依赖的jar包

commons-lang
commons-lang
2.4
org.springframework
spring-core
3.0.3.RELEASE
org.springframework
spring-context
3.0.3.RELEASE
org.springframework
spring-tx
3.0.3.RELEASE
org.springframework
spring-context-support
3.0.3.RELEASE
org.apache.zookeeper
zookeeper
3.4.6
org.apache.curator
curator-framework
2.4.2
org.apache.curator
curator-recipes
2.4.2

相关资料:

转载于:https://my.oschina.net/boltwu/blog/729240

你可能感兴趣的文章
java中通过绝对路径将图片存入数据库
查看>>
ConcurrentHashMap(Java8)源码分析
查看>>
Python文件处理之文件指针(四)
查看>>
Numpy用法详解
查看>>
DataGridView在vb.net中的操作技巧
查看>>
PMP考试冲刺进行中。。。
查看>>
大换血的代价
查看>>
RunLoop--
查看>>
chrome 2行换行省略号 ... text-ellipse
查看>>
C语言第四次作业
查看>>
Java学习-集合的理解
查看>>
iOS验证码倒计时(GCD实现)
查看>>
iOS中的过滤器和正则表达式(NSPredicate,NSRegularExpression)
查看>>
canvas和svg
查看>>
结对:复利美化版
查看>>
HDU_2689_Sort it
查看>>
urllib模块使用笔记
查看>>
mysql 连接慢的问题(超过了1秒)
查看>>
Linux嵌入式GDB调试环境搭建
查看>>
java分析jvm常用指令
查看>>