微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Zookeeper中watcher触发none事件的原因

首先,下面的表格是所有事件类型和触发条件,大体分为两类,一是连接状态事件(EventType=None),二是节点事件

 然后直接看代码

public class zkClient {

    private String connectString="hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout=100000;
    private ZooKeeper zkClient = null;

    @Before
    public void init() throws IOException {

        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                if ( watchedEvent.getType() == null || "".equals( watchedEvent.getType())) {
                    return;
                }
                System.out.println("已经触发了" +  watchedEvent.getType() + "事件!");
            }
        });

    }

    @Test
    public void getChildren() throws KeeperException, InterruptedException {
       //List<String> children = zkClient.getChildren("/", true);
    Thread.sleep(Long.MAX_VALUE); } }

这里我们执行getChildren(),由于@Before会先执行init()连接服务端,然后直接进入睡眠状态。

执行结果:

 已经触发了None事件!

可以看到,客户端与服务端成功建立会话触发了None事件。即使没有注册watcher,同样触发了连接状态事件

然后我们使用另一台客户端删除一个节点,控制台什么都没有打印。说明节点事件需要注册才能触发

接下来我们加入getChildren()函数进行watcher注册

package com.weng.zk;

import org.apache.zookeeper.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class zkClient {


    private String connectString="hadoop102:2181,hadoop103:2181,hadoop104:2181";
    private int sessionTimeout=100000;
    private ZooKeeper zkClient = null;


    @Before
    public void init() throws IOException {

        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                if ( watchedEvent.getType() == null || "".equals( watchedEvent.getType())) {
                    return;
                }
                System.out.println("已经触发了" +  watchedEvent.getType() + "事件!");
            }
        });

    }


    @Test
    public void getChildren() throws KeeperException, InterruptedException {
        List<String> children = zkClient.getChildren("/", true);
        Thread.sleep(Long.MAX_VALUE);
    }
}

执行结果:

已经触发了None事件!

 然后我们在另一台客户端删除一个子节点

已经触发了nodechildrenChanged事件!

 再删除一个子节点,控制台没有再打印。

 

为什么有且只打印了两次呢?

第一次打印的是连接状态事件(EventType=None)客户端与服务端成功建立会话触发,不需要注册

第二次打印的是节点事件,我们注册了并在另一台客户端删除一个子节点,触发了该事件。

但节点事件具有一次性,一旦被触发就会被移除。所有再删除一个子节点也不会继续打印。

 

结论:

watcher处理的事件分为两类

一是连接状态事件,无需注册,一旦发生就会触发。

二是节点事件,需要注册才能触发,且一次注册只能触发一次。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐