ZooKeeper zkCli = new ZooKeeper("192.168.50.183:2181,192.168.50.184:2181,192.168.50.185:2181", 3000, new Watcher() {
//监听回调
@Override
public void process(WatchedEvent event) {
System.out.println("正在监听中.....");
}
});
通过zkCli.getchildren("/",new watch()){}来注册监听,监听的是整个根节点,但是这个监听只能监听一次。
线程休眠是为了让监听等待事件发生,不然会随着程序直接运行完。
public class WatchDemo1 {
static List children = null;
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zkCli = new ZooKeeper("192.168.50.183:2181,192.168.50.184:2181,192.168.50.185:2181", 3000, new Watcher() {
//监听回调
@Override
public void process(WatchedEvent event) {
System.out.println("正在监听中.....");
}
});
//监听目录
children = zkCli.getChildren("/", new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println("监听路径为:" + event.getPath());
System.out.println("监听的类型为:" + event.getType());
System.out.println("数据被2货修改了!!!");
for(String c:children) {
System.out.println(c);
}
}
});
Thread.sleep(Long.MAX_VALUE);
}
}
可以通过修改zk客户端的/节点下的子节点,getchilren会返回列表(/下的子节点信息)
getData监听的为一个节点
同样只监听一次,返回的是该节点的内容
public class WatchDemo {
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zkCli = new ZooKeeper("192.168.50.183:2181,192.168.50.184:2181,192.168.50.185:2181", 3000, new Watcher() {
//监听回调
@Override
public void process(WatchedEvent event) {
}
});
byte[] data = zkCli.getData("/hunter", new Watcher() {
//监听的具体内容
@Override
public void process(WatchedEvent event) {
System.out.println("监听路径为:" + event.getPath());
System.out.println("监听的类型为:" + event.getType());
System.out.println("数据被2货修改了!!!");
}
}, null);
System.out.println(new String(data));
Thread.sleep(Long.MAX_VALUE);
}
}
public class ZkClient {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
//1.获取连接
ZkClient zkClient = new ZkClient();
zkClient.getConnect();
//2.监听服务的节点信息
zkClient.getServers();;
//3.业务逻辑(一直监听)
zkClient.getWatch();
}
//3.业务逻辑
public void getWatch() throws InterruptedException {
Thread.sleep(Long.MAX_VALUE);
}
//2.监听服务的节点信息
public void getServers() throws KeeperException, InterruptedException {
List children = zkCli.getChildren("/servers", true);
ArrayList serverList = new ArrayList();
//获取每个节点的数据
for(String c:children) {
byte[] data = zkCli.getData("/servers/" + c, true, null);
serverList.add(new String(data));
}
//打印服务器列表
System.out.println(serverList);
}
private String connectString = "192.168.232.132:2181,192.168.232.133:2181,192.168.232.134:2181";
private int sessionTimeout = 3000;
ZooKeeper zkCli;
//1.连接集群
public void getConnect() throws IOException {
zkCli = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
List children;
try {
//监听父节点
children = zkCli.getChildren("/servers", true);
//创建集合存储服务器列表
ArrayList serverList = new ArrayList();
//获取每个节点的数据
for(String c:children) {
byte[] data = zkCli.getData("/servers/" + c, true, null);
serverList.add(new String(data));
}
//打印服务器列表
System.out.println(serverList);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
服务端上下线机器,客户端都能动态感知,这里是先通过getchilren获得根节点下的子节点信息列表,然后通过getData来获得每个子节点的内容,并传给ArrayList,最后通过输出ArrayList来获得当前在线的机器
1.从1-3的代码可以看出,zookeeper注册的监听是一次的,如果你还需要监听第二次,那么就要重新注册。
那我们永久监听是怎么做到的呢?
2.可以看到在我们连接zookeeper的时候,注册了监听,然后在process方法中,我们的getChildren,getData的第二个参数为true,这里是使用默认的监听,我的理解是会回调到我们连接zookeeper的时候注册监听的process方法,那因为我们的getChildren,getData是放在这个方法里的,每次发生一个事件,然后就一直重复这样的行为,达到永久监听的效果。
3.这里我们可以测试下,getChildren,getData不放在process当中,并且参数为true,那我的测试结果为,监听了一次,监听完了后,又返回连接zk时的process方法中的语句.这里就证明了我的理解应该是对了。