ZooKeeper可以统一修改集群中的配置信息,主要使用它的watcher功能。
下面表格列出了写操作与ZK内部产生的事件的对应关系:

而ZK内部的写事件与所触发的watcher的对应关系如下:

实现永久监听:
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
public class ZooKeeperWatcherDemo {
static final String CONNECT_ADDR = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";
static final int SESSION_OUTTIME = 2000;//ms
/** * 阻塞程序执行,等待zookeeper连接成功 */
static final CountDownLatch connectedSemaphore = new CountDownLatch(1);
static final String PATH = "/configroot";
public static void main(String[] args) { try {
//连接 ZooKeeper zk = new ZooKeeper(CONNECT_ADDR, SESSION_OUTTIME, event -> {
System.out.println("事件是:"+event.getType());
//如果收到了服务端的响应事件,连接成功
if (Watcher.Event.KeeperState.SyncConnected == event.getState()) {
connectedSemaphore.countDown(); } });
connectedSemaphore.await();
System.out.println("连接成功!");
System.out.println(zk.getState());
zk.create(PATH, "0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//可以绑定事件的操作:getData、exists、getChildren // 通过exists绑定事件 //如果第二个参数为true,事件会触发至创建该ZooKeeper中的Watcher中 //Stat stat = zk.exists(PATH,true); //在当前exists中单独触发一个事件
Stat stat = zk.exists(PATH, event -> {
System.out.println(event.getType() + "--->" + event.getPath());
try { zk.exists(event.getPath(),true); //在次触发事件
} catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } });
//触发Watcher事件
Stat stat2 = zk.setData(PATH, "1".getBytes(), stat.getVersion());
Thread.sleep(1000);
zk.delete(PATH,stat2.getVersion());
zk.close();
} catch (IOException | InterruptedException | KeeperException e) { e.printStackTrace(); } }}
网友评论