[ZooKeeper ]基于Java API 实践

ZooKeeper 基于Java API 实践

前提

建立maven项目中 要导入zookeeper的依赖

<dependency>
      <groupId>org.apache.zookeepergroupId>
      <artifactId>zookeeperartifactId>
      <version>3.4.8version>
    dependency>

一、建立连接

直接建立连接后,不进行等待判断 运行结果为连接中(CONNECTING)。

清单1 连接中 zookeeper
    // 一、没有连接成功
    public static void main(String[] args) {

        // zookeeper集群 ip  :客户端口
        String kvm="192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181";

        try {
            ZooKeeper zooKeeper=new ZooKeeper(kvm,4000,null);
            // CONNECTING  连接中   ==》根据zookeeper的四个状态,可知、;没有连接成功
            System.out.println(zooKeeper.getState()); 
            zooKeeper.close();                          // 关闭连接
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

添加CountDownLatch同步工具类.

清单2 连接zookeeper成功
   // 二、连接成功   zookeeper
    /**
     * 同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。
     */
    public static void main(String[] args) {
        final CountDownLatch countDownLatch=new CountDownLatch(1);
        String kvm="192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181";

        try {
            ZooKeeper zooKeeper=new ZooKeeper(kvm, 4000, new Watcher() {
                // process: 观察者队列
                @Override
                public void process(WatchedEvent watchedEvent) {
                    //  SyncConnected  :同步连接
                    if(Event.KeeperState.SyncConnected==watchedEvent.getState()){
                        // 如果收到服务端的响应时间,连接成功

                        countDownLatch.countDown();
                        System.out.println("建立连接成功");
                    }

                }
            });

            countDownLatch.await();
            System.out.println(zooKeeper.getState()); // CONNECTED  :连接成功
            zooKeeper.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

二、数据的增删改查操作

基于代码的增删改查操作,我们可以去到zookeeper中的zkCli客户端窗口中去验证。
进入zkCli客户端窗口:在bin目录下 直接输入 zkCli.sh 回车,便可进入。

清单1 事务操作
 public static void main(String[] args) {

        try {
            final CountDownLatch countDownLatch=new CountDownLatch(1);
            java.lang.String kvm="192.168.0.11:2181,192.168.0.13:2181,192.168.0.12:2181";

            java.lang.String kvm2="192.168.0.85:2181";

            ZooKeeper zooKeeper =new ZooKeeper(kvm, 4000, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {

                    if (Event.KeeperState.SyncConnected==watchedEvent.getState()){
                        countDownLatch.countDown();//如果收到了服务端的响应时间,连接成功
                        System.out.println("zk 建立连接");
                    }
                }
            });
            countDownLatch.await();


            System.out.println(zooKeeper.getState());// connected  成功

            /**
             * zookeeper数据的增删改查
             */
            // 1.新增节点
            zooKeeper.create("/zk-wcl","0".getBytes(), 
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

            Thread.sleep(1000);
            Stat stat=new Stat();// 状态
            // 2.查看新增后的节点状态
            byte[] bytes=zooKeeper.getData("/zk-wcl",null,stat);

            System.out.println(new String(bytes));
            // 3.修改节点
            zooKeeper.setData("/zk-wcl","1".getBytes(),stat.getVersion());

            // 4.查看修改后的节点状态
            byte[] byte2=zooKeeper.getData("/zk-wcl",null,stat);
            System.out.println(new String(byte2));


            // 5.删除节点
            zooKeeper.delete("/zk-wcl",stat.getVersion());


            zooKeeper.close();
            System.in.read();// 当前进程阻塞
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (KeeperException e) {
            e.printStackTrace();
        }


    }

三、事件机制

介绍
1、如何注册事件机制

分为两步:绑定事件、触发事件。
第一步:通过getDateexistsgetChildren这三个操作来绑定事件。
第二步:凡是事务类型的操作,都会触发监听事件。
事务操作:create 、“delete`、setData“`

清单1:创建删除节点的事件注册监听实例
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        /*------------------基于Java API 建立连接---------------------------*/
        final CountDownLatch countDownLatch=new CountDownLatch(1);
        java.lang.String kvm="192.168.0.11:2181,192.168.0.13:2181,192.168.0.12:2181";

        java.lang.String kvm2="192.168.0.85:2181";
        // TODO: 这儿是全局的Watcher
        ZooKeeper zooKeeper =new ZooKeeper(kvm, 4000, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                // 默认事件
                System.out.println("默认事件:"+watchedEvent.getType());
                if (Event.KeeperState.SyncConnected==watchedEvent.getState()){
                    countDownLatch.countDown();//如果收到了服务端的响应时间,连接成功
                    System.out.println("zk 建立连接");
                }
            }
        });
        countDownLatch.await();

        /*--------------如何注册、监听事件机制-------------------------*/
        // 一、去创建一个临时节点
        zooKeeper.create("/zk-test-wcl","1".getBytes(),
                ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);


        /**
         * 二、针对这个节点 绑定事件  3 种方式
         * (exists getdata getchildren)
         * 解释:
         * zooKeeper.exists(String path,Watcher watcher)中的参数
         * watcher为true时,代表默认触发全局 zookeeper 中的内部类
         *
         * 演示:
         * 我们以 exists 来 绑定事件
         */
        Stat stat=zooKeeper.exists("/zk-test-wcl", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println(watchedEvent.getType()+"-->"+watchedEvent.getPath());
                // TODO:NOTE ==> 因为watcher是一次性操作,
                //              只能看到setData操作带来的变化,delete操作看不到变化。
                // TODO:NOTE ==> 所以,要在绑定一次事件,来持续监听

                try {
                    // TODO :注意true 默认用的是全局的watcher
                    zooKeeper.exists(watchedEvent.getPath(),true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // 通过修改的事务类型操作来触发监听事件
        // TODO:1、setData
       stat = zooKeeper.setData("/zk-test-wcl","2".getBytes(),
                stat.getVersion());
        Thread.sleep(1000);
        // TODO: 2、delete
        zooKeeper.delete("/zk-test-wcl",stat.getVersion());
        System.in.read();
    }

2、watcher事件类型
事件类型 含义
None(-1) 客户端连接状态发生改变时,会受到none事件
NodeCreated(1) 创建节点事件
NodeDeleted(2) 删除节点事件
NodeDataChanged(3) 节点数据发生变更
NodeChildrenChanged(4) 子节点被创建、被删除会发生事件触发
3、什么样的操作会产生什么类型的事件

待续。。。。

4、事件的实现原理

你可能感兴趣的:(ZooKeeper)