使用zookeeper原生API链接ZK集群进行基本API演示(2)

前面一篇介绍了使用zk原生api链接zk集群进行基本api的演示,演示了连接zk初始化的过程和创建节点的过程。本篇演示获取子节点,获取数据的同步异步获取代码demo.

package com.coderman.zookeeper.clusterdemo.version2;

import com.alibaba.fastjson.JSON;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @description:
 * @author: Fanchunshuai
 * @time: 2020/2/10 17:14
 */
public class GetChildrenAPIDemo implements Watcher {
    private static StringBuffer buffer = new StringBuffer();
    private static CountDownLatch countDownLatch = new CountDownLatch(1);
    private static final int SESSION_TIMEOUT = 5000;
    protected static ZooKeeper zooKeeper;
    private static Stat stat = new Stat();

    static {
        buffer.append("192.168.1.224:2184,");
        buffer.append("192.168.1.224:2181,");
        buffer.append("192.168.1.224:2182,");
        buffer.append("192.168.1.224:2183,");
        buffer.append("192.168.1.224:2185");
    }

    public static void main(String[] args) throws InterruptedException, IOException, KeeperException {
        //getChildrenSync();
        //getChildrenASync();
        getDataAPI();
    }

    /**
     * 同步获取子节点
     * @throws IOException
     * @throws InterruptedException
     * @throws KeeperException
     */
    private static void getChildrenSync() throws IOException, InterruptedException, KeeperException {
        String path = "/zk-demo2";
        zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
        countDownLatch.await();
        //同步创建一个持久节点
        zooKeeper.create(path,"".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //同步创建一个临时子节点
        zooKeeper.create(path+"/children1","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        //获取子节点的时候,通过第二个参数注册监听器
        List<String> nodes = zooKeeper.getChildren(path,true);
        System.out.println(JSON.toJSONString(nodes));
        //重新创建子节点
        zooKeeper.create(path+"/children2","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        Thread.sleep(1000000L);
    }

    /**
     * 异步获取子节点
     * 异步接口通常应用在这样的使用场景中:应用启动的时候,
     * 会获取一些配置信息,例如机器配置表等,这些配置通常比较大,并且不希望
     * 配置的获取影响应用的主流程。
     * @throws IOException
     * @throws InterruptedException
     * @throws KeeperException
     */
    private static void getChildrenASync() throws IOException, InterruptedException, KeeperException {
        String path = "/zk-demo3";
        zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
        countDownLatch.await();
        //同步创建一个持久节点
        zooKeeper.create(path,"".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //同步创建一个临时子节点
        zooKeeper.create(path+"/children1","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
        //获取子节点的时候,通过第二个参数注册自定义监听器
        zooKeeper.getChildren(path,true,new IChildren2Callback(),null);
        //重新创建子节点
        zooKeeper.create(path+"/children2","".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);


        Thread.sleep(1000000L);
    }

    /**
     *
     * getData Api
     * 返回的数据是byte[]类型
     * @throws IOException
     * @throws InterruptedException
     * @throws KeeperException
     */
    private static void getDataAPI() throws IOException, InterruptedException, KeeperException {
        String path = "/zk-demo4";
        zooKeeper = new ZooKeeper(buffer.toString(),SESSION_TIMEOUT,new GetChildrenAPIDemo());
        countDownLatch.await();
        zooKeeper.create(path,"123456".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);
        //这里是同步调用,也可以有异步调用,异步调用的回调函数使用DataCallBack接口作为回调函数
        String data = new String(zooKeeper.getData(path,true,stat));
        System.out.println(stat.getCzxid()+","+stat.getMzxid());
        zooKeeper.setData(path,"1212".getBytes(),-1);
        //异步调用获取数据
        zooKeeper.getData(path, true, new IDataCallBack(),null);
        Thread.sleep(Integer.MAX_VALUE);
    }


    @Override
    public void process(WatchedEvent watchedEvent) {
        if(Event.KeeperState.SyncConnected == watchedEvent.getState()){
            if(Event.EventType.None == watchedEvent.getType() && null == watchedEvent.getPath()){
                countDownLatch.countDown();
            }
            //子节点变更监听
            //这里需要说明的是zk服务器在向客户端发送Watcher
            //"NodeChildrenChanaged"事件通知的时候,仅仅只会
            //发出一个通知,而不会把节点变化的情况发送给客户端,需要客户端自己
            //重新获取。另外Watcher通知是一次性的,触发通知之后
            //就失效了,因此客户端需要重复注册Watcher
            else if(Event.EventType.NodeChildrenChanged == watchedEvent.getType()){
                try {
                    System.out.println("reget the changed child node = "+zooKeeper.getChildren(watchedEvent.getPath(),true));
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //监听节点数据变化
            else if(Event.EventType.NodeDataChanged == watchedEvent.getType()){
                try {
                    System.out.println(new String(zooKeeper.getData(watchedEvent.getPath(),true,stat)));
                    System.out.println(stat.getCzxid()+","+stat.getMzxid()+","+stat.getVersion());
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 自定义回调函数
     */
    static class IChildren2Callback implements AsyncCallback.Children2Callback{
        @Override
        public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
            System.out.println("Get children znode result = [response code  : "+rc+",path = "+path+",ctx = "+ctx
            +",stat = "+stat);
        }
    }

    /**
     * 数据类型的回调函数
     */
    static class IDataCallBack implements AsyncCallback.DataCallback{
        @Override
        public void processResult(int i, String s, Object o, byte[] bytes, Stat stat) {
            System.out.println("rc = "+i+",path = "+s+",data = "+new String(bytes));
            System.out.println(stat.getCzxid()+","+stat.getMzxid()+","+stat.getVersion());
        }
    }

}

发布了166 篇原创文章 · 获赞 71 · 访问量 35万+

猜你喜欢

转载自blog.csdn.net/u010504064/article/details/104252626