ZooKeeper的Watcher总结
发布日期:2021-05-07 11:25:37 浏览次数:20 分类:精选文章

本文共 4016 字,大约阅读时间需要 13 分钟。

ZooKeeper3.4.10版本Watcher触发关系详解

写操作与读操作函数的Watcher触发关系

在ZooKeeper3.4.10版本中,写操作(create、set、delete)与读操作(exists、getData、getChildren)之间通过Watcher机制建立了特定的触发关系。以下表格详细说明了不同操作对应的事件类型。

节点操作 读操作 事件类型
创建节点 exists NodeCreated
创建子节点 exists NodeCreated
创建子节点 getChildren NodeChildrenChanged
修改节点 exists NodeDataChanged
修改子节点 exists NodeDataChanged
删除子节点 exists NodeDeleted
删除子节点 getData NodeDeleted
删除子节点 getChildren NodeDeleted
删除节点 exists NodeDeleted
删除节点 getData NodeDeleted
删除节点 getChildren NodeDeleted

详细说明

  • 创建节点

    当创建节点时,触发节点的exists函数的Watcher,事件类型为NodeCreated

  • 创建子节点

    创建子节点时,触发子节点的exists函数的Watcher,事件类型为NodeCreated。同时,触发父节点的getChildren函数的Watcher,事件类型为NodeChildrenChanged

  • 修改节点

    修改节点时,触发节点的existsgetData函数的Watcher,事件类型均为NodeDataChanged

  • 修改子节点

    修改子节点时,触发子节点的existsgetData函数的Watcher,事件类型均为NodeDataChanged

  • 删除子节点

    删除子节点时,触发子节点的existsgetDatagetChildren函数的Watcher,事件类型分别为NodeDeletedNodeDeletedNodeDeleted

  • 删除节点

    删除节点时,触发节点的existsgetDatagetChildren函数的Watcher,事件类型均为NodeDeleted

  • 注意事项

  • 删除节点时触发getChildren

    删除节点时,不仅会触发节点的getChildren函数的Watcher,还会继续触发其getDataexists函数的Watcher。

  • 删除子节点时触发多个事件

    删除子节点时,不仅会触发子节点的getChildren函数的Watcher,还会同时触发父节点的getChildren函数的Watcher,事件类型不同。

  • 只有创建与删除子节点才会触发getChildren

    修改子节点不会触发父节点的getChildren函数的Watcher。

  • 测试代码示例

    public class ZooKeeperUtils {
    public static ZooKeeper getZKConn(String hosts) throws IOException {
    int sessionTimeout = 3000;
    System.out.println("连接到ZooKeeper...");
    ZooKeeper zooKeeper = new ZooKeeper(hosts, sessionTimeout, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("连接事件:" + event.getState());
    }
    });
    System.out.println("连接成功!");
    return zooKeeper;
    }
    public static void testWatcher(String host) throws Exception {
    String path = "/test";
    String pathChild = "/test/test1";
    ZooKeeper zooKeeper = getZKConn(host);
    // 注册"/test"的exists watcher
    Stat stat = zooKeeper.exists(path, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("exists: " + event.getType());
    }
    });
    if (stat != null) {
    // 注册"/test"的getData watcher
    zooKeeper.getData(path, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("getData: " + event.getType());
    }
    }, new Stat());
    // 注册"/test"的getChildren watcher
    zooKeeper.getChildren(path, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("getChildren: " + event.getType());
    }
    });
    }
    // 注册"/test/test1"的exists watcher
    Stat statChild = zooKeeper.exists(pathChild, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("child exists: " + event.getType());
    }
    });
    if (statChild != null) {
    // 注册"/test/test1"的getData watcher
    zooKeeper.getData(pathChild, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("child getData: " + event.getType());
    }
    }, new Stat());
    // 注册"/test/test1"的getChildren watcher
    zooKeeper.getChildren(pathChild, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    System.out.println("child getChildren: " + event.getType());
    }
    });
    }
    public static void main(String[] args) throws Exception {
    String host = "192.168.56.1:2181";
    testWatcher(host);
    while (true) {
    // 保持连接 alive
    }
    }
    }
    }

    注意事项

    在进行一次写操作之前,需要重新运行程序,因为Watcher只能触发一次。

    上一篇:容器启动报错:exec user process caused “no such file or directory“
    下一篇:《算法(第4版)》--堆排序

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2025年04月21日 14时48分30秒

    关于作者

        喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
    -- 愿君每日到此一游!

    推荐文章