zookeeper watch java_ZooKeeper Watch Java API浅析exists

Watch是ZooKeeper中非常重要的一个机制,它可以监控ZooKeeper中节点的变化情况,告知客户端。下面,我们以代码为例来分析Watch在ZooKeeper中是如何实现的。ZooKeeper中一共由三种方法可以实现Watch,分别为getData、exists和getChildren,今天我们先来看下exists()方法:

2、exists()

import java.io.IOException;

import org.apache.zookeeper.CreateMode;

import org.apache.zookeeper.KeeperException;

import org.apache.zookeeper.WatchedEvent;

import org.apache.zookeeper.Watcher;

import org.apache.zookeeper.ZooKeeper;

import org.apache.zookeeper.ZooDefs.Ids;

import org.apache.zookeeper.data.Stat;

public class TestZooKeeperWatcher {

public static void main(String[] args) {

ZooKeeper zk = null;

try {

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("开始连接ZooKeeper...");

// 创建与ZooKeeper服务器的连接zk

String address = "192.168.1.226:2181";

int sessionTimeout = 3000;

zk = new ZooKeeper(address, sessionTimeout, new Watcher() {

// 监控所有被触发的事件

public void process(WatchedEvent event) {

if (event.getType() == null || "".equals(event.getType())) {

return;

}

System.out.println("已经触发了" + event.getType() + "事件!");

}

});

System.out.println("ZooKeeper连接创建成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 创建根目录节点

// 路径为/tmp_root_path

// 节点内容为字符串"我是根目录/tmp_root_path"

// 创建模式为CreateMode.PERSISTENT

System.out.println("开始创建根目录节点/tmp_root_path...");

zk.create("/tmp_root_path", "我是根目录/tmp_root_path".getBytes(),

Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

System.out.println("根目录节点/tmp_root_path创建成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 创建第一个子目录节点

// 路径为/tmp_root_path/childPath1

// 节点内容为字符串"我是第一个子目录/tmp_root_path/childPath1"

// 创建模式为CreateMode.PERSISTENT

System.out.println("开始创建第一个子目录节点/tmp_root_path/childPath1...");

zk.create("/tmp_root_path/childPath1",

"我是第一个子目录/tmp_root_path/childPath1".getBytes(),

Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

System.out.println("第一个子目录节点/tmp_root_path/childPath1创建成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 创建第二个子目录节点

// 路径为/tmp_root_path/childPath2

// 节点内容为字符串"我是第二个子目录/tmp_root_path/childPath2"

// 创建模式为CreateMode.PERSISTENT

System.out.println("开始创建第二个子目录节点/tmp_root_path/childPath2...");

zk.create("/tmp_root_path/childPath2",

"我是第二个子目录/tmp_root_path/childPath2".getBytes(),

Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

System.out.println("第二个子目录节点/tmp_root_path/childPath2创建成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 修改第一个子目录节点/tmp_root_path/childPath1数据

System.out.println("开始修改第一个子目录节点/tmp_root_path/childPath1数据...");

zk.setData("/tmp_root_path/childPath1",

"我是修改数据后的第一个子目录/tmp_root_path/childPath1".getBytes(), -1);

System.out.println("修改第一个子目录节点/tmp_root_path/childPath1数据成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 修改第二个子目录节点/tmp_root_path/childPath2数据

System.out.println("开始修改第二个子目录节点/tmp_root_path/childPath2数据...");

zk.setData("/tmp_root_path/childPath2",

"我是修改数据后的第二个子目录/tmp_root_path/childPath2".getBytes(), -1);

System.out.println("修改第二个子目录节点/tmp_root_path/childPath2数据成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 获取根目录节点状态

System.out.println("开始获取根目录节点状态...");

System.out.println(zk.exists("/tmp_root_path", true));

System.out.println("根目录节点状态获取成功");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 删除第一个子目录节点

System.out.println("开始删除第一个子目录节点/tmp_root_path/childPath1...");

zk.delete("/tmp_root_path/childPath1", -1);

System.out.println("第一个子目录节点/tmp_root_path/childPath1删除成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 删除第二个子目录节点

System.out.println("开始删除第二个子目录节点/tmp_root_path/childPath2...");

zk.delete("/tmp_root_path/childPath2", -1);

System.out.println("第二个子目录节点/tmp_root_path/childPath2删除成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

// 删除根目录节点

System.out.println("开始删除根目录节点/tmp_root_path...");

zk.delete("/tmp_root_path", -1);

System.out.println("根目录节点/tmp_root_path删除成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

} catch (IOException | KeeperException | InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

// 关闭连接

if (zk != null) {

try {

zk.close();

System.out.println("释放ZooKeeper连接成功!");

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

}        执行结果如下:

...

...

...

...

开始连接ZooKeeper...

ZooKeeper连接创建成功!

已经触发了None事件!

...

...

...

...

开始创建根目录节点/tmp_root_path...

根目录节点/tmp_root_path创建成功!

...

...

...

...

开始创建第一个子目录节点/tmp_root_path/childPath1...

第一个子目录节点/tmp_root_path/childPath1创建成功!

...

...

...

...

...

...

...

...

开始创建第二个子目录节点/tmp_root_path/childPath2...

第二个子目录节点/tmp_root_path/childPath2创建成功!

...

...

...

...

开始修改第一个子目录节点/tmp_root_path/childPath1数据...

修改第一个子目录节点/tmp_root_path/childPath1数据成功!

...

...

...

...

开始修改第二个子目录节点/tmp_root_path/childPath2数据...

修改第二个子目录节点/tmp_root_path/childPath2数据成功!

...

...

...

...

开始获取根目录节点状态...

2007741,2007741,1458963342014,1458963342014,0,2,0,0,29,2,2007743

根目录节点状态获取成功

...

...

...

...

开始删除第一个子目录节点/tmp_root_path/childPath1...

第一个子目录节点/tmp_root_path/childPath1删除成功!

...

...

...

...

开始删除第二个子目录节点/tmp_root_path/childPath2...

第二个子目录节点/tmp_root_path/childPath2删除成功!

...

...

...

...

开始删除根目录节点/tmp_root_path...

已经触发了NodeDeleted事件!

根目录节点/tmp_root_path删除成功!

...

...

...

...

释放ZooKeeper连接成功!        而如果我们在获取根目录节点状态之后,修改根目录数据,添加代码和执行结果如下:

// 修改根目录节点数据

System.out.println("开始修改根目录节点/tmp_root_path数据...");

zk.setData("/tmp_root_path",

"我是修改数据后的根目录/tmp_root_path".getBytes(), -1);

System.out.println("修改根目录节点/tmp_root_path数据成功!");

Thread.currentThread().sleep(1000l);

System.out.println("...");

System.out.println("...");

System.out.println("...");

System.out.println("...");

...

...

...

...

开始连接ZooKeeper...

ZooKeeper连接创建成功!

已经触发了None事件!

...

...

...

...

开始创建根目录节点/tmp_root_path...

根目录节点/tmp_root_path创建成功!

...

...

...

...

开始创建第一个子目录节点/tmp_root_path/childPath1...

第一个子目录节点/tmp_root_path/childPath1创建成功!

...

...

...

...

...

...

...

...

开始创建第二个子目录节点/tmp_root_path/childPath2...

第二个子目录节点/tmp_root_path/childPath2创建成功!

...

...

...

...

开始修改第一个子目录节点/tmp_root_path/childPath1数据...

修改第一个子目录节点/tmp_root_path/childPath1数据成功!

...

...

...

...

开始修改第二个子目录节点/tmp_root_path/childPath2数据...

修改第二个子目录节点/tmp_root_path/childPath2数据成功!

...

...

...

...

开始获取根目录节点状态...

2007775,2007775,1458963528012,1458963528012,0,2,0,0,29,2,2007777

根目录节点状态获取成功

...

...

...

...

开始修改根目录节点/tmp_root_path数据...

已经触发了NodeDataChanged事件!

修改根目录节点/tmp_root_path数据成功!

...

...

...

...

开始删除第一个子目录节点/tmp_root_path/childPath1...

第一个子目录节点/tmp_root_path/childPath1删除成功!

...

...

...

...

开始删除第二个子目录节点/tmp_root_path/childPath2...

第二个子目录节点/tmp_root_path/childPath2删除成功!

...

...

...

...

开始删除根目录节点/tmp_root_path...

根目录节点/tmp_root_path删除成功!

...

...

...

...

释放ZooKeeper连接成功!        与getData()一致!

结论:         exists()方法仅仅监控对应节点的一次数据变化,无论是数据修改还是删除!若要每次对应节点发生变化都被监测到,那么每次都得先调用exists()方法获取一遍节点状态!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值