项目越来越大,涉及的外围项目也是越来越多,多个项目间难免会有些共同的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的值
再看后台输出
这样就可以在不停机的状态下动态的修改一些初始化数据的值,实现项目之间的解耦。