基于 Java API 初探 zookeeper 的使用 一

1.如何连接zookeeper客户端

package com.arcln.zookeeper;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

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

/**
 * 原生的 zookeeper API
 */
public class ConnectionDemo {
    public static void main(String[] args) throws Exception {
        final CountDownLatch downLatch = new CountDownLatch(1);
        final ZooKeeper zookeeper = new ZooKeeper("192.168.1.128:2181,192.168.1.129:2181,192.168.1.130:2181",
                4000,
                new Watcher() {
                    @Override
                    public void process(WatchedEvent event) {
                        if(event.getState() == Event.KeeperState.SyncConnected){
                            downLatch.countDown();
                        }
                    }
                });
        downLatch.await(); //为了等待zooKeeper连接成功
        System.out.println("连接状态--------->"+zookeeper.getState()+" <--------------");
        String nodeName = "/zk-persis-TEST";
        /** 创建节点
         * @param String path, 节点路径
         * @param byte[] data, value值
         * @param List<ACL> acl, 开放权限
         * @param  CreateMode createMode,存储模式
         */
        zookeeper.create(nodeName,"0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        //Stat中保存了zookeeper节点中对应的所有信息
        Stat stat = new Stat();
        //得到当前的节点
        byte[] bytes = zookeeper.getData(nodeName,null,stat);
        System.out.println("创建时的值:"+new String(bytes)+" ");

        //修改节点
        zookeeper.setData(nodeName,"1".getBytes(),stat.getVersion());

        //得到当前的节点
        byte[] bytes1 = zookeeper.getData(nodeName,null,stat);
        System.out.println("修改后的值:"+new String(bytes1)+" ");

        //删除
        zookeeper.delete(nodeName,stat.getVersion());
        zookeeper.close();
       // System.in.read();
    }
}

2.事件机制

   Watcher监听机制是Zookeeper中非常重要的特性,基于Zookeeper上创建的节点,可以对这些节点绑定监听事体,比如监听节点数据的变更,节点删除,子节点状态变更,通过这个事件机制,可以基于zookeeper实现分布式锁,集群管理功能

   watcher特性:当数据发生变化的时候,zookeeper会产生一个watcher事件,并且会发送到客户端,但是客户端只会收到一次通知,如果后续这个节点再次发生变化,那么之前设置watcher的客户端面不会再次收到消息(可能通过循环监听达到永久监听的效果)。

   如何注册事件机制

    通过这三个操作来绑定事件:getData、Exists、getChildren

    如何触发事件?

    凡是事务类型的操作,都会触发监听事件。create /delete/setDatawatcher


package com.arcln.zookeeper;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.util.concurrent.CountDownLatch;

public class WatcherDemo {
    public static void main(String[] args) throws Exception {
        final CountDownLatch downLatch = new CountDownLatch(1);
        final ZooKeeper zookeeper = new ZooKeeper(
           "192.168.1.128:2181,192.168.1.129:2181,192.168.1.130:2181", 4000,
                new Watcher() {
                    @Override
                    public void process(WatchedEvent event) {
                        //全局默认事
                        if(event.getState() == Event.KeeperState.SyncConnected)
                            downLatch.countDown();
                    }
                });
        downLatch.await();
        String path = "/zk-persis-b";
        zookeeper.create(path,"x".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

        //通过  exists  getData  getchildren 绑定事件
        //通过 exists绑定事件,watcher只会绑定一次事件
        Stat stat = zookeeper.exists(path, new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println(watchedEvent.getType()+"->"+watchedEvent.getPath());
                try {
                    zookeeper.exists(watchedEvent.getPath(),true);
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        //通过修改值 ,来触发事件
        stat = zookeeper.setData(path,"y".getBytes(),stat.getVersion());
        //通过删除值 ,来触发事件
        zookeeper.delete(path,stat.getVersion());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章