Java API操作

6.1 原生 API

1)Maven依赖

<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.6</version>
            <type>pom</type>
        </dependency>

2)相关操作

(1)获得客户端对象
private  ZooKeeper zooKeeper;

    @Before
    public void getCline() throws Exception{

         zooKeeper = new ZooKeeper("192.168.134.99:2181",2000,null);

    }
(2)获取节点值
@Test
    public void getData()throws Exception{

        /*获取节点值*/
        byte[] data = zooKeeper.getData("/ba/123", null, null);
        System.out.println(new String(data));
    }
(3)获取节点孩子
@Test
    public void getChild() throws Exception{

        /*获取当前输入节点下的子节点*/
        List<String> children = zooKeeper.getChildren("/ba/gjf", null);
        children.forEach((a)->{
            System.out.println(a);
        });

    }
(4)创建节点
@Test
    public void createNode() throws Exception{


        /*创建持久节点*/

        Object value = null;

        value = "12312312";


        byte[] bytes = ((String) value).getBytes();


        String s = zooKeeper.create("/ba/123", bytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println(s);




    }
(5)更新节点值
@Test
    public void setData() throws Exception{

        Stat stat = zooKeeper.setData("/ba/123", new String("123123").getBytes(), -1);

        System.out.println(stat);


    }
(6)判断节点是否存在
@Test
    public void exist() throws Exception{

        Stat stat = zooKeeper.exists("/ba/13", false);

        if (stat==null) {
            System.out.println("该节点不存在!");
        }else {
            System.out.println("该节点存在!");
        }

    }

6.2 zkCline API

1)Mavne依赖

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.8</version>
</dependency>

2)核心API

ZkClient client=new ZkClient("ip:port");

3)相关操作

package test;

import org.I0Itec.zkclient.ZkClient;

import java.util.List;

/**
 * Create by GuoJF on 2019/3/12
 */
public class Main {
    public static void main(String[] args) {


        ZkClient zkClient = new ZkClient("192.168.134.5:2181");


        /*
        * 获取根目录下所有的node信息
        *
        * */
        List<String> children = zkClient.getChildren("/");

        children.forEach((a)->{
            System.out.println(a);
        });

    }
}

(1)创建节点

@Test
    public void createNode() {

        String result = zkClient.create("/ba/001", "001", CreateMode.PERSISTENT);

        System.out.println(result);

    }

(2)获取节点

@Test
    public void getData() {
        Object readData = zkClient.readData("/ba/001");

        System.out.println(readData.toString());

    }

(3)更新节点值

@Test
    public void setData() {
        zkClient.writeData("/ba/001", "123123");
    }

(4)删除节点

@Test
    public void delNode() {

        boolean delete = zkClient.delete("/ba/001");
        if (delete) {
            System.out.println("删除成功!");
        } else {
            System.out.println("删除失败或者节点不存在!");
        }
    }

(5)判断节点是否存在

@Test
    public void exist(){

        boolean exists = zkClient.exists("/ba/001");
        if (exists){
            System.out.println("该节点已经存在!");
        }else {
            System.out.println("该节点不存在!");
        }

    }

(6)获取孩子节点

@Test
    public void getChild(){

        List<String> children = zkClient.getChildren("/ba");

        for (String child : children) {

            System.out.println(child);
        }
    }

6.3 Curator API

1)Maven依赖

<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-framework</artifactId>
   <version>2.7.1</version>
 </dependency>

2)相关操作

(1)获取客户端对象
private CuratorFramework curatorFramework;

    @Before
    public void getClient() {

        /*
         * 重连策略 四种实现
         *  ExponentialBackoffRetry、RetryNTimes、RetryOneTimes、RetryUntilElapsed
         * */


        ExponentialBackoffRetry backoffRetry = new ExponentialBackoffRetry(1000, 1000);

        curatorFramework = CuratorFrameworkFactory.newClient("192.168.134.99:2181", backoffRetry);

        curatorFramework.start();


    }
(2)创建节点
@Test
    public void createNode() throws Exception {
    String s = curatorFramework.create().withMode(CreateMode.PERSISTENT).forPath("/ba/002", new String("123").getBytes());
        System.out.println(s);
    }
(3)获取节点
@Test
    public void getData() throws Exception {

        byte[] bytes = curatorFramework.getData().forPath("/ba/002");

        System.out.println(new String(bytes));
    }
(4)更新节点值
@Test
    public void setData() {

        try {
            curatorFramework.setData().forPath("/ba/001", new String("123123").getBytes());

            System.out.println("更新成功!");
        } catch (KeeperException.NoNodeException e) {

            System.out.println("更新失败,该节点不存在!");
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
(5)获取孩子节点
@Test
    public void getChild() throws Exception {
        curatorFramework.getChildren().forPath("/ba").forEach((child) -> {
            System.out.println(child);
        });
    }
(6)删除节点
@Test
    public void delNode() throws Exception {
        curatorFramework.delete().forPath("/ba/002");
    }

6.4 Watcher接口

1)原生API实现Watch接口

在这里使用的是原生的Apache的Java API

<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
	<groupId>org.apache.zookeeper</groupId>
		<artifactId>zookeeper</artifactId>
	<version>3.4.6</version>
	<type>pom</type>
</dependency>

ZooKeeper Watcher监视使客户端能够接收来自ZooKeeper服务器的通知,并在发生时处理这些事件。 ZooKeeper Java API提供了一个名为Watcher的公共接口,客户端事件处理程序类必须实现该接口才能接收有关来自ZooKeeper服务器的事件通知。 以编程方式,使用这种客户端的应用程序通过向客户端注册回调(callback)对象来处理这些事件。

package test;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.UUID;

/**
 * Create by GuoJF on 2019/3/12
 */
public class DataUpdater  {

    private static String hostPort = "192.168.134.5:2181";
    private static String zooDataPath = "/ba/gjf";
    ZooKeeper zk;

    public DataUpdater() throws IOException {
        try {
            zk = new ZooKeeper(hostPort, 2000, null);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() throws InterruptedException, KeeperException {
        while (true) {
            String uuid = UUID.randomUUID().toString();
            byte zoo_data[] = uuid.getBytes();
            zk.setData(zooDataPath, zoo_data, -1);
            try {
                Thread.sleep(5000); // Sleep for 5 secs
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        DataUpdater dataUpdater = new DataUpdater();
        dataUpdater.run();
    }
}
package test;


import org.apache.zookeeper.*;

/**
 * Create by GuoJF on 2019/3/13
 */
public class DataWatcher implements Watcher,Runnable {


    ZooKeeper zooKeeper;

    public DataWatcher() {

        try {
              zooKeeper = new ZooKeeper("192.168.134.5:2181",2000,this);

              if (zooKeeper.exists("/ba/gjf",this)==null) {

                  zooKeeper.create("/ba/gjf", "get".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

              }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {

        DataWatcher dataWatcher = new DataWatcher();

        dataWatcher.run();

    }


    @Override
    public void process(WatchedEvent event) {

        if (event.getType() == Event.EventType.NodeDataChanged){
            System.out.println("数据发改变了吧");

            try {
                byte[] data = zooKeeper.getData("/ba/gjf", this, null);

                String s = new String(data);

                System.out.println(s);

            }catch (Exception e){

            }

        }

    }

    public void run() {
        try {
            synchronized (this) {
                while (true) {
                    wait();
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }
}

2)ZkClient实现Watcher接口

@Test
    public void watcherInterface() throws Exception {
        zkClient.subscribeDataChanges("/ba/gjf", new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("节点名称:" + dataPath);
                System.out.println("节点名称:" + data.toString());

            }

            @Override
            public void handleDataDeleted(String dataPath) throws Exception {

            }
        });


        Thread.sleep(Integer.MAX_VALUE);
    }

3)Curator API实现Watcher接口

ZooKeeper原生的API支持通过注册Watcher来进行事件监听,但是Watcher通知是一次性的,因此开发过程中需要反复注册Watcher,比较繁琐。Curator引入了Cache来监听ZooKeeper服务端的事件。Cache对ZooKeeper事件监听进行了封装,能够自动处理反复注册监听,简化了ZooKeeper原生API繁琐的开发过程。

<dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>2.7.1</version>
        </dependency>
(1)NodeCache

监听指定的数据变化

/*
         *NodeCache
         *
         * */

        //在注册监听器的时候,如果传入此参数,当事件触发时,逻辑由线程池处理
        ExecutorService pool = Executors.newFixedThreadPool(2);

        NodeCache nodeCache = new NodeCache(curatorFramework, "/ba/gjf", false);

        nodeCache.start(true);

        nodeCache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println(new String(nodeCache.getCurrentData().getData()));
            }
        }, pool);
(2)PathChildrenCache

监听指定节点下所有子节点的数据变化

/**
         * 监听子节点的变化情况
         */
        PathChildrenCache childrenCache = new PathChildrenCache(curatorFramework, "/ba", true);
        childrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);
        childrenCache.getListenable().addListener(
                new PathChildrenCacheListener() {
                    @Override
                    public void childEvent(CuratorFramework client, PathChildrenCacheEvent event)
                            throws Exception {
                        switch (event.getType()) {
                            case CHILD_ADDED:
                                System.out.println("CHILD_ADDED: " + event.getData().getPath());
                                break;
                            case CHILD_REMOVED:
                                System.out.println("CHILD_REMOVED: " + event.getData().getPath());
                                break;
                            case CHILD_UPDATED:
                                System.out.println("CHILD_UPDATED: " + event.getData().getPath());
                                break;
                            default:
                                break;
                        }
                    }
                },
                pool
        );