有时候,我们用Zookeeper来做配置管理,但是,我们怎么知道配置信息何时发生改变?客户端怎么能自己感知Zookeeper里面的配置信息发生的改变呢?
Watcher机制,不过默认只能监控一次(一旦配置信息发生改变)。一次性的代码如下:
@Test
public void testWatcherOnce() throws KeeperException, InterruptedException {
Stat stat = new Stat();
String path = "/server/address";
// 回调函数
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent event) {
System.err.println("zookeeper的配置信息发生改变了");
}
};
zooKeeper.getData(path, watcher, stat);
while(true) {
Thread.sleep(5000);
System.err.println("我还活着呢!!!!!");
}
}
测试启动后,修改zookeeper中/server/address 里面的值,
测试结果:
后面不管你改多少次,也不会检测到内容的变化。因此我们需要把代码做些调整。
/**
* @Description: 以递归方式实现节点状态的持续监控的方法
* @author yunyao.huang
* @throws InterruptedException
* @throws KeeperException
* @date 2018年8月7日
*/
public String doProcess(final String path, final Stat stat) throws KeeperException, InterruptedException {
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent event) {
try {
// 核心思想就是这步,方法调方法
String innerResult = doProcess(path,stat);
String[] addressArray = innerResult.split(",");
for (String address : addressArray) {
System.err.println("ping " + address);
}
} catch (KeeperException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
byte[] data = zooKeeper.getData(path, watcher, stat);
return new String(data);
}
核心思想就是以递归的方式来持续检测节点变化。(当然方法不止这一种,读者可以自行研究)
测试一下:
@Test
public void testProcess() throws KeeperException, InterruptedException {
Stat stat = new Stat();
String path = "/server/address";
String initResult = doProcess(path, stat);
System.err.println("initResult ==> " + initResult);
while(true) {
Thread.sleep(5000);
System.err.println("我还活着呢!!!!!");
}
}
测试结果:
在企业开发中,我们的项目部署的ip可能因为规模的增大和并发的问题,需要部署集群,我们可以把它们的ip信息,存放在zookeeper的某个路径下,用来做订阅,让客户端能够持续知道服务器ip的变化,从而能够做出合适的请求。