- Watcher机制
客户端向zk服务器注册watcher的同时,会将watcher对象存储在客户端的watchManager,Zk服务器触发watcher事件后,会向客户端发送通知,客户端线程从watchManager中݊调起watcher执行。
客户端的处理流程
服务器端处理流程
2 Java代码实现
Maven依赖:
<dependencies>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.11</version>
</dependency>
</dependencies>
public class ZookeeperUtil extends Thread {
private static final String zkConnectString = "localhost:2181";
private static ZooKeeper zooKeeper = null;
private static final String NODE_PATH = "/test";
private static Watcher dataWatcher = new Watcher() {
public void process(WatchedEvent event) {
System.out.println("进入process方法。。。");
ZooKeeper zk = getZk();
System.out.println("事件类型:" + event.getState());
System.out.println(event.getType());
System.out.println(event.getPath());
if (event.getType() == EventType.NodeDataChanged) {
try {
System.out.println("进入。。。");
if (NODE_PATH.equals(event.getPath())) {
byte[] data = zk.getData(event.getPath(), dataWatcher, new Stat());
// 数据变更
String str = new String(data, "UTF-8");
System.out.println("变更数据为:" + str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
public static ZooKeeper getZk() {
try {
if (zooKeeper == null) {
zooKeeper = new ZooKeeper(zkConnectString, 6000, dataWatcher);
}
System.out.println("获取Zookeeper连接成功");
} catch (Exception e) {
e.printStackTrace();
}
return zooKeeper;
}
@Override
public synchronized void start() {
synchronized (this) {
while (true) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
ZooKeeper zk = getZk();
if (zk != null) {
byte[] data = zk.getData(NODE_PATH, dataWatcher, new Stat());
String strData = new String(data, "UTF-8");
System.out.println("初始值:" + strData);
}
new ZookeeperUtil().start();// 启动一个线程,一个让main线程不会马上死掉。
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("run over");
}
}
启动main函数后,打开Zookeeper的客户端,修改数据后,将会出现如下:
运行截图:
之所以启动一个线程,同时让他进入睡眠的状态,是想让main线程不会马上死掉,当数据变更时,main线程中会触发process方法,输出变更后的数据信息。