Zookeeper Java API操作流程

首先需要配置一台Zookeeper服务器

pom文件

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.6.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework -->
        <!--Zookeeper客户端基础包-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes -->
        <!--Zookeeper客户端曾强包-->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

实现节点的增删改查

/**
 * 实现节点的增删改查
 * 方式1:创建一个空永久节点(只能创建一个节点)
 * 方式2:创建一个有内容永久的空节点(只能创建一层节点)
 * 方式3:创建多层节点
 * 是否需要创建父节点creatingParentsIfNeeded()
 * 节点的创建模式 withMode(模式) 方法
 * 参数CreateMode.PERSISTENT 创建持久性节点
 * 参数CreateMode.PERSISTENT_SEQUENTIAL 创建带有序号的持久性节点
 * 参数CreateMode.EPHEMERAL 创建临时性节点(客户端关闭,节点消失)
 * 参数CreateMode.EPHEMERAL_SEQUENTIAL 创建带有序号的临时节点(客户端关闭,节点消失)
 */
public class zkDemo {
    private CuratorFramework client = null;

    /**
     * 创建客户端
     * 步骤:
     * 1、创建连接失败重试策略对象
     * 2、创建连接客户端
     */
    @Before
    public void createClient() {
        //1.创建连接失败重试策略对象
        //RetryPolIcy接口 失败重试策略的公共接口;ExponentialBackoffRetry实现类,是失败重试策略的接口实现类
        //参数1:两次重试之间等待的初始化时间(单位毫秒)
        //参数2:最大重试次数
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 3);

        //2.创建客户端对象
        //参数1:连接Zookeeper服务的IP地址和端口号
        //参数2:会话超时时间(单位毫秒)
        //参数3:连接超时时间(单位毫秒)
        //参数4:失败重试策略对象
        client = CuratorFrameworkFactory.newClient("节点的IP地址:2181", 1000, 1000, retryPolicy);
    }

    /**
     * 创建节点(创建一个空节点)
     * 1、开启客户端(会阻塞到会话连接成功为止)
     * 2、创建节点
     * 3、关闭客户端
     *
     * @throws Exception 异常行为
     */
    @Test
    public void createNode01() throws Exception {
        //创建一个空节点
        client.create().forPath("/app1");
    }

    /**
     * 创建节点(创建一个有内容的空节点)
     * 1、开启客户端(会阻塞到会话连接成功为止)
     * 2、创建节点
     * 3、关闭客户端
     *
     * @throws Exception 异常行为
     */
    @Test
    public void createNode02() throws Exception {
        //创建一个有内容的空节点
        client.create().forPath("/app2", "App2 Node".getBytes());
    }

    /**
     * 创建节点(创建多层节点)
     * 1、开启客户端(会阻塞到会话连接成功为止)
     * 2、创建节点
     * 3、关闭客户端
     *
     * @throws Exception 异常行为
     */
    @Test
    public void createNode03() throws Exception {
        //创建多层节点
        client.create().creatingParentsIfNeeded().forPath("/app4/data", "App4 Node".getBytes());
    }

    /**
     * 创建节点(创建临时性节点)
     * 1、开启客户端(会阻塞到会话连接成功为止)
     * 2、创建节点
     * 3、关闭客户端
     *
     * @throws Exception 异常行为
     */
    @Test
    public void createNode04() throws Exception {
        //创建临时性节点
        client.create().withMode(CreateMode.EPHEMERAL)
                .forPath("/app5", "App5 Node".getBytes());
    }

    /**
     * 创建节点(创建带序号的永久节点)
     * 1、开启客户端(会阻塞到会话连接成功为止)
     * 2、创建节点
     * 3、关闭客户端
     *
     * @throws Exception 异常行为
     */
    @Test
    public void createNode05() throws Exception {
        client.create().withMode(CreateMode.CONTAINER)
                .forPath("/app6", "App6 Node".getBytes());
    }

    /**
     * 修改节点数据
     * 步骤:
     * 1、启动客户端
     * 2、修改节点
     * 3、关闭客户端
     */
    @Test
    public void modifyNode() throws Exception {
        //启动客户端
        client.start();
        //修改节点数据
        client.setData().forPath("/app1", "app1 Node".getBytes());
        //关闭客户端
        client.close();
    }

    /**
     * 获取节点数据
     * 步骤:
     * 1、启动客户端
     * 2、获取节点数据
     * 3、关闭客户端
     */
    @Test
    public void findNodeData() throws Exception {
        //启动客户端
        client.start();
        //获取节点数据(返回字节数组)
        byte[] bytes = client.getData().forPath("/app2");
        System.out.println("App2节点数据=" + new String(bytes));
        //关闭客户端
        client.close();
    }

    /**
     * 节点的删除(正常删除一个子节点)
     * 步骤:
     * 1、启动客户端
     * 2、删除节点
     * 3、关闭客户端
     */
    @Test
    public void deleteNode01() throws Exception {
        //启动客户端
        client.start();
        //正常删除一个子节点
        client.delete().forPath("/app1");
        //关闭客户端
        client.close();
    }

    /**
     * 节点的删除(递归删除一个子节点)
     * 步骤:
     * 1、启动客户端
     * 2、删除节点
     * 3、关闭客户端
     */
    @Test
    public void deleteNode02() throws Exception {
        //启动客户端
        client.start();
        //递归删除一个子节点
        client.delete().deletingChildrenIfNeeded().forPath("/app4");
        //关闭客户端
        client.close();
    }

    /**
     * 节点的删除(强制保证删除一个节点)
     * 比如遇到一些网络异常的情况,此guaranteed的强制删除会很有效果
     * 步骤:
     * 1、启动客户端
     * 2、删除节点
     * 3、关闭客户端
     */
    @Test
    public void deleteNode03() throws Exception{
        //启动客户端
        client.start();
        //保证强制删除一个节点
        client.delete().guaranteed().forPath("/app5");
        //关闭客户端
        client.close();
    }
}

Zookeeper的监听机制

/**
 * Zookeeper的监听机制
 */
public class ZkWatch {
    /**
     * NodeCache是用来监听节点数据变化的,当监听的节点的数据发生变化时就会回调对应的函数
     * 步骤:
     * 1、创建重试策略
     * 2、创建客户端使用重试策略
     * 3、开启客户端
     * 4、创建节点数据监听对象
     * 5、开始缓存(true:可以直接获取监听节点。false:不可以获取监听的节点)
     * 6、添加监听对象(如果节点数据有变化,会回调该方法)
     *
     * @throws Exception 失败异常
     */
    @Test
    public void nodeCacheTest() throws Exception {
        //1.创建重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 3);
        //2.创建客户端
        CuratorFramework client = CuratorFrameworkFactory
                .newClient("192.168.10.101:2181", 1000, 1000, retryPolicy);

        //3.开启客户端
        client.start();
        System.out.println("连接Zookeeper服务成功");

        //4.创建节点监听对象 NodeCache(参数1:哪个客户端,参数2:监听那个节点)
        final NodeCache nodeCache = new NodeCache(client, "/hello");

        //5.开始缓存(true:可以直接获取监听节点。false:不可以获取监听的节点)
        nodeCache.start(true);

        //6.添加监听对象(如果节点数据有变化,会回调该方法)
        nodeCache.getListenable().addListener(new NodeCacheListener() {
            public void nodeChanged() throws Exception {
                //如果回调方法被调用,获取节点中最新的数据
                ChildData data = nodeCache.getCurrentData();
                //打印最新节点数据
                System.out.println("节点数据: path ==> " + data.getPath() + " 数据内容: ==> " + new String(data.getData()));
            }
        });
        //阻塞程序的执行,让程序一直执行
        System.in.read();
    }


    /**
     * PathChildrenCache是用来监听指定节点的子节点变化情况
     * 步骤:
     * 1、创建重试策略
     * 2、创建客户端,使用重试策略
     * 3、开启客户端
     * 4、创建节点的数据监控对象
     * 5、开始缓存(设置启动模式)
     * 6、添加监听对象(如果节点有变化,会回调该方法)
     *
     * @throws Exception 失败异常
     */
    @Test
    public void nodePathChildrenCache() throws Exception {
        //1.创建重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 3);

        //2.创建客户端,使用重试策略
        CuratorFramework client = CuratorFrameworkFactory
                .newClient("192.168.10.101:2181", 1000, 1000, retryPolicy);

        //3.开启客户端
        client.start();

        //4.创建节点的数据监控对象(参数1:连接对象,参数2:节点名称,参数3:[如果为false则无法读取到数据内容,如果为true则客户端在接收到节点列表改变的同时,也能够获取到节点数据内容])
        final PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/hello", true);

        //5.开始缓存(设置启动模式)
        //三种启动模式:
        // 1、NORMAL:普通启动模式,在启动时缓存子节点数据
        // 2、POST_INITIALIZED_EVENT:在启动时缓存节点数据,提示初始化
        // 3、BUILD_INITIAL_CACHE:在启动时什么都不会输出
        pathChildrenCache.start(PathChildrenCache.StartMode.POST_INITIALIZED_EVENT);

        //6.添加监听对象(如果节点有变化,会回调该方法)
        pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
            /**
             * 一共有7种事件类型
             * 1.PathChildrenEvent.CHILD_ADDED 子节点添加,
             * 2.PathChildrenEvent.CHILD_UPDATED 子节点修改,
             * 3.PathChildrenEvent.CHILD_REMOVED 子节点删除,
             * 4.PathChildrenEvent.CONNECTION_SUSPENDED 连接超时,
             * 5.PathChildrenEvent.CONNECTION_RECONNECTED, 重新连接
             * 6.PathChildrenEvent.CONNECTION_LOST, 连接超时一段时间
             * 7.PathChildrenEvent.INITIALIZED 初始化完成;
             * @param curatorFramework 客户端对象
             * @param Event 当前监听的节点事件对象
             * @throws Exception 异常
             */
            public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent Event) throws Exception {
                //回调方法
                //子节点添加
                if (Event.getType() == PathChildrenCacheEvent.Type.CHILD_ADDED) {
                    System.out.println("添加了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == PathChildrenCacheEvent.Type.CHILD_UPDATED) {
                    System.out.println("修改了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == PathChildrenCacheEvent.Type.CHILD_REMOVED) {
                    System.out.println("删除了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == PathChildrenCacheEvent.Type.CONNECTION_SUSPENDED) {
                    System.out.println("连接超时");
                } else if (Event.getType() == PathChildrenCacheEvent.Type.CONNECTION_RECONNECTED) {
                    System.out.println("重新连接");
                } else if (Event.getType() == PathChildrenCacheEvent.Type.CONNECTION_LOST) {
                    System.out.println("连接超时一段时间");
                } else if (Event.getType() == PathChildrenCacheEvent.Type.INITIALIZED) {
                    System.out.println("初始化完成");
                }
            }
        });
        //阻塞程序的执行,让程序一直执行
        System.in.read();
    }

    /***
     * TreeCache既能够监听自节点的变化,也能够监听子节点的变化【重要,需牢记】
     * 步骤:
     * 1、创建连接重试策略
     * 2、创建客户端,使用重试策略
     * 3、开启客户端
     * 4、创建节点的数据监听对象
     * 5、开始缓存
     * 6、添加监听对象(如果节点数据有变化,会回调该方法)
     * @throws Exception 异常
     */
    @Test
    public void nodeTreeCache() throws Exception {
        //1.创建重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 3);

        //2.创建客户端,使用重试策略
        CuratorFramework client = CuratorFrameworkFactory
                .newClient("192.168.10.101:2181", 1000, 1000, retryPolicy);

        //3.开启客户端
        client.start();

        //4.创建节点的数据监听对象
        //参数1:连接对象
        //参数2:节点名称
        TreeCache treeCache = new TreeCache(client, "/hello");

        //5.开始缓存
        treeCache.start();

        //6.添加监听对象(如果节点数据有变化,会回调该方法)
        //TreeCacheEvent.Type.NODE_ADDED, 子节点添加
        //TreeCacheEvent.Type.NODE_UPDATED, 子节点更新
        //TreeCacheEvent.Type.NODE_REMOVED, 子节点删除
        //TreeCacheEvent.Type.CONNECTION_SUSPENDED, 待定
        //TreeCacheEvent.Type.CONNECTION_RECONNECTED, 重新连接
        //TreeCacheEvent.Type.CONNECTION_LOST, 连接超时一段时间
        //TreeCacheEvent.Type.INITIALIZED, 初始化完成
        treeCache.getListenable().addListener(new TreeCacheListener() {
            public void childEvent(CuratorFramework client, TreeCacheEvent Event) throws Exception {
                if (Event.getType() == TreeCacheEvent.Type.NODE_ADDED) {
                    System.out.println("添加了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == TreeCacheEvent.Type.NODE_UPDATED) {
                    System.out.println("更新了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == TreeCacheEvent.Type.NODE_REMOVED) {
                    System.out.println("删除了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == TreeCacheEvent.Type.CONNECTION_SUSPENDED) {
                    System.out.println("暂停了一个子节点; 节点路径==>" + Event.getData().getPath() + " 节点数据==>" + new String(Event.getData().getData()));
                } else if (Event.getType() == TreeCacheEvent.Type.CONNECTION_RECONNECTED) {
                    System.out.println("重新连接了");
                } else if (Event.getType() == TreeCacheEvent.Type.CONNECTION_LOST) {
                    System.out.println("连接超时了一段时间");
                } else if (Event.getType() == TreeCacheEvent.Type.INITIALIZED) {
                    System.out.println("初始化完成");
                }
            }
        });
        //阻塞程序的执行,让程序一直执行
        System.in.read();
    }
}
posted @ 2024-01-31 09:09  MineLSG  阅读(6)  评论(0编辑  收藏  举报