Zookeeper设置监视点

本文详细介绍了如何在Zookeeper中使用监视点进行节点状态监控。包括如何通过getData、getChildren和exists等API设置监视点,并捕捉节点创建、删除、数据变更及子节点变化等事件。同时探讨了监视点的一次性触发特性及其应对策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Zookeeper的API中的getData、getChildren和exists均可选择在读取的znode 上设置监视点。使用监视点,我们可以使用Watcher接口在process(WatchedEvent event)中捕获event

1. WatchEvent说明

  1. zk会话状态:KeeperState
    在这里插入图片描述
  2. 事件类型:EventType
    在这里插入图片描述
    示例代码:
    @Override
    public void process(WatchedEvent watchedEvent) {
        System.out.println("ZNodeWatcher Process Event:"+watchedEvent);
        //获取会话状态
        Event.KeeperState ks = watchedEvent.getState();
        //获取事件状态
        Event.EventType ev = watchedEvent.getType();
    }

2. 监视点类型

监视点类型设置方法
NodeCreateexists
NodeDeleteexists \ getData
NodeDataChangedgetData
NodeChildrenChangedgetChildren

例如:

  //getdata 使用自定义watcher设置监视点
  public byte[] getData(String path, Watcher watcher, Stat stat)
  //使用默认watcher设置监视点
  public byte[] getData(String path, boolean watch, Stat stat)

对于第二种与第一种的不同只是采用了默认的watcher
第二种方法源码:

 public byte[] getData(String path, boolean watch, Stat stat) throws KeeperException, InterruptedException {
        return this.getData(path, watch ? this.watchManager.defaultWatcher : null, stat);
    }

3. 使用exists添加监视点

  1. 构造一个节点的监视点
 Watcher nodeExistsWatcher= new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            String msg = "Node Exists Watcher Event:"+event.toString();
            System.out.println(msg);
           if(event.getType() == Event.EventType.NodeDeleted){
               System.out.println(">> 节点:"+watchNode+" 被删除!");
               assert watchNode.equals(event.getPath());
               //监视点被触发一次就会失效,因此要重新添加
               addExistsWatch();
            }else if(event.getType() == Event.EventType.NodeCreated){
               System.out.println(">> 节点:"+watchNode+" 被添加!");
               assert watchNode.equals(event.getPath());
               //节点添加后重新添加监视点
               addExistsWatch();
           }
        }
    };
  1. 构造一个创建监视点的回调方法
AsyncCallback.StatCallback nodeExistsCallback = new AsyncCallback.StatCallback() {
        @Override
        public void processResult(int i, String s, Object o, Stat stat) {
            String msg = "Node Exists Callback: Code:"+i+" Path:"+s;
            System.out.println(msg);
            switch (KeeperException.Code.get(i)){
                case CONNECTIONLOSS:
                    //连接丢失重新添加监视点
                    System.out.println("连接丢失!重新添加监视点!");
                    addExistsWatch();
                    break;
                case OK:
                    System.out.println("OK,Stat:"+stat);
                    break;
                case NONODE:
                    System.out.println("NONODE");
                    break;
                case NODEEXISTS:
                    System.out.println("NODEEXISTS");
                    break;
                default:
                    break;
            }
        }
    };
  1. 创建监视点
 public void addExistsWatch(){
        zk.exists(watchNode,
                nodeExistsWatcher,
                nodeExistsCallback,
                null
                );
    }

注意
4. 监视点是单次触发,既触发一次后就失效,因此,我们在 nodeExistsWatcherprocess 方法中触发一次后又重新添加;
5. exists方法仅能触发NodeDeleted,和NodeCreated,如果想触发NodeDataChangedNodeChildrenChanged还需要添加getDatagetChildren方法

	public void addNodeWatch() {
        Stat stat = new Stat();
        try{
            byte data[] = zk.getData(watchNode,
                    nodeWatcher,
                    stat
            );
            String v = new String(data);
            System.out.println(">>增加监视点,节点:"+watchNode+" 值:"+v);
        }catch (KeeperException.NoNodeException ex){
            System.out.println(">>添加节点监控点异常,节点:"+watchNode+" 不存在!");
        }catch (KeeperException.ConnectionLossException ex){
            ex.printStackTrace();
        }catch (KeeperException ex){
            ex.printStackTrace();
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }
    }

    public void addChildrenNodeWatch() {
        Stat stat = new Stat();
        try{
            List<String> nodes = zk.getChildren(watchNode,
                    nodeWatcher,
                    stat
            );
            System.out.println(">>增加监视点,节点:"+watchNode+" 子节点列表:");
            for (String node:nodes) {
                System.out.println(">>子节点:"+node);
            }
        }catch (KeeperException.NoNodeException ex){
            System.out.println(">>添加节点监控点异常,节点:"+watchNode+" 不存在!");
        }catch (KeeperException.ConnectionLossException ex){
            ex.printStackTrace();
        }catch (KeeperException ex){
            ex.printStackTrace();
        }catch (InterruptedException ex){
            ex.printStackTrace();
        }
    }

重新定义nodewatch,增加对NodeDataChangedNodeChildrenChanged的监视

Watcher nodeWatcher = new Watcher() {
        @Override
        public void process(WatchedEvent event) {
            String msg = "Node Exists Watcher Event:"+event.toString();
            System.out.println(msg);
           if(event.getType() == Event.EventType.NodeDeleted){
               System.out.println(">> 节点:"+watchNode+" 被删除!");
               assert watchNode.equals(event.getPath());
               //节点删除后重新添加监视点
               addExistsWatch();
            }else if(event.getType() == Event.EventType.NodeCreated){
               System.out.println(">> 节点:"+watchNode+" 被添加!");
               assert watchNode.equals(event.getPath());
               //节点创建后可以增加getData和getChild方法的监视点
               addNodeWatch();
               addChildrenNodeWatch();
           }else if(event.getType() == Event.EventType.NodeDataChanged){
               System.out.println(">> 节点:"+watchNode+" 值修改!");
               assert watchNode.equals(event.getPath());
               //NodeDataChanged触发后重新添加监视点
               addNodeWatch();
           }else if(event.getType() == Event.EventType.NodeChildrenChanged){
               System.out.println(">> 节点:"+watchNode+" 子节点变化!");
               assert watchNode.equals(event.getPath());
               //NodeChildrenChanged触发后重新添加监视点
               addChildrenNodeWatch();
           }
        }
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值