zookeeper编程--如何通过zookeeper动态初始化项目属性值

项目越来越大,涉及的外围项目也是越来越多,多个项目间难免会有些共同的ip、port、需要监
控的交易连接等,如果每个项目都有一份配置文件,如果有一天需要修改ip或者修改一些密码什么
的难免需要重启所有项目,涉及是项目一多,就容易有遗忘或者出错,现将这些公共信息全部配置
在zookeeper中,外围项目需要的信息全部上zookeeper取值,则大大减小项目间的耦合性

现在多个外围系统有很多配置,以后将逐步将配置文件全提到zookeeper上保存,在此环境下,此次的模块拆分就将部分配置文件放置于zookeeper。

zookeeper的集群配置很简单,此处不再赘述,zookeeper提供了两个方法来获取节点内容,同步获取和异步获取:

public byte[] getData(String path, boolean watch, Stat stat);

public void getData(final String path, Watcher watcher,
            DataCallback cb, Object ctx);

path    指定数据节点的路径,获取该节点下面的子节点
watcher 注册在path上的Watcher。节点变更会通知会向客户端发起通知。
stat    指定数据节点状态信息。传入旧stat,方法执行过程中会将其替换为新stat对象。
watch   表示是否需要注册一个watcher。true:注册默认watcher,false:不需要注册watcher
cb  注册一个异步回调函数
ctx 传递上下文信息

此次项目采用的是同步的方式获取节点内容。
我采用的是zookeeper集群,通过./zkCli.sh -timeout 5000 -server 20.4.16.10:2181 的方式进入客户端,进入任意一个即可 ,创建一个节点backlist 并赋值为backlist create /backlist backlist

这里写图片描述


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;

public class Test implements Watcher {
    private ZooKeeper zk;

    private String zookeeperUrl;
    private int zookeeperTimeOut;
    private HashMap<String, String> valAndPath = Maps.newHashMap();

    public static void main(String[] args) throws Exception {
        Test h = new Test();
        //相应时长
        h.zookeeperTimeOut = 3000;
        //集群ip
        h.zookeeperUrl = "20.4.16.9:2181,20.4.16.10:2181,20.4.16.35:2181";
        h.valAndPath = Maps.newHashMap();
        h.valAndPath.put("/backlist", "123");
        h.zooKeeperInitial();

        while (true) {
            System.out.println("backlist is " + h.getValAndPath().get("/backlist"));
            TimeUnit.SECONDS.sleep(1L);
        }
    }

    public void zooKeeperInitial() throws Exception {
        try {
            zk = new ZooKeeper(zookeeperUrl, zookeeperTimeOut, this);
            for (Map.Entry<String, String> entry : valAndPath.entrySet()) {
                String value = getValFromZooKeeper(entry.getKey());
                if (!Strings.isNullOrEmpty(value)) {
                    valAndPath.put(entry.getKey(), value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            // 弱依赖
            // throw e;
        }
    }


    @Override
    public void process(WatchedEvent paramWatchedEvent) {
        System.out.println(" 已经触发了[" + paramWatchedEvent.toString() + "]事件!");
        String path = paramWatchedEvent.getPath();
        try {
            updateValue(path);
        } catch (Exception e) {
            System.out.println("更新ZooKeeper配置异常" + e);
        }
    }

    private void updateValue(String path) throws KeeperException, InterruptedException {
        String value = getValFromZooKeeper(path);
        if (!Strings.isNullOrEmpty(value)) {
            valAndPath.put(path, value);
        }
    }

    public ZooKeeper getZk() {
        return zk;
    }

    public void setZk(ZooKeeper zk) {
        this.zk = zk;
    }

    public String getZookeeperUrl() {
        return zookeeperUrl;
    }

    public void setZookeeperUrl(String zookeeperUrl) {
        this.zookeeperUrl = zookeeperUrl;
    }

    public int getZookeeperTimeOut() {
        return zookeeperTimeOut;
    }

    public void setZookeeperTimeOut(int zookeeperTimeOut) {
        this.zookeeperTimeOut = zookeeperTimeOut;
    }

    public HashMap<String, String> getValAndPath() {
        return valAndPath;
    }

    public void setValAndPath(HashMap<String, String> valAndPath) {
        this.valAndPath = valAndPath;
    }

}

来看下启动打印的日志

这里写图片描述

然后我在后台修改 backlist的值
这里写图片描述
再看后台输出

这里写图片描述

这样就可以在不停机的状态下动态的修改一些初始化数据的值,实现项目之间的解耦。

猜你喜欢

转载自blog.csdn.net/xuxie13/article/details/79198229