Zookeeper技术内幕之Curator客户端

4、Zookeeper技术内幕之Curator客户端

4.4 Curator客户端

4.4.1 简介

       Curator是Netflix公司开源的一套zk客户端开源框架,与ZkClient一样,其也封装了zk原生的API。其目前已经成为Apache顶级项目。同时,Curator还提供了一套易用性、可读性更强的Fluent风格的客户端API框架。

 

4.4.2 API介绍

       这里主要以Fluent风格客户端API为主进行介绍。

(1)创建会话

       A、普通API创建newClient()

       在CuratorFrameworkFactory类中,提供了两个静态方法用于完成会话创建。

       查看这些方法的源码可以看到具体参数名称,这些参数的意义为:

       B、Fluent风格创建

 

(2)创建节点create()

       下面使用的client为前面所创建的Curator客户端。

       创建一个节点,初始内容为空

       语句:client.create().forPath(PATH);

       说明:默认创建的是持久节点,数据内容为空。

 

       创建一个节点,附带初始内容

       语句:client.create().forPath(PATH, "mydata".getBytes());

       说明:Curator在指定数据内容时,只能使用byte[]作为方法参数。

 

       创建一个临时节点,初始内容为空

       语句:client.create().withMode(CreateMode.EPHEMERAL).forPath(PATH);

       说明:CreateMode为枚举类型。

 

       创建一个临时节点,并自动递归创建父节点

       语句:client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(PATH);

       说明:若指定节点多级父节点均不存在,则会自动创建。

 

(3)删除节点delete()

       删除一个节点

       语句:client.delete().forPath(PATH);

       说明:只能将叶子节点删除,其父节点不能删除。

 

       删除一个节点,并递归删除其所有的子节点

       语句:client.delete().deletingChildrenIfNeeded().forPath(PATH);

       说明:该方法使用时需谨慎。

 

(4)更新数据setData()

       设置一个节点的数据内容

       语句:client.setData().forPath(PATH, newData);

       说明:该方法具有返回值,返回值为Stat状态对象。

 

(5)检查节点是否存在checkExits()

       检查节点是否存在

       语句:client.checkExists().forPath(PATH);

       说明:该方法具有返回值,返回值为Stat状态对象。若stat为null,说明该节点不存在,否则说明该节点是存在的。   

 

(6)获取节点数据内容getData()

       获取一个节点数据内容

      语句:byte[] data = client.getData().forPath(PATH);

       说明:其返回值为byte[]数组。

 

(7)获取子节点列表

       获取一个节点的子节点所有列表

       语句:List<String> childrenNames = client.getChildren().forPath(PATH);

       说明:返回值为List<String>

 

(8)watcher注册usingWatcher()   

       curator绑定watcher的操作有三个:checkExits()、getData()、getChildren()。这三个方法的共性是,它们都是用来获取的。这三个操作用于watcher注册的方法是相同的,都是使用usingWatcher()方法。

这两个方法中的参数CuratorWatcher和Watcher都为接口。这两个接口都包含一个方法process(),它们的区别是,CuratorWatcher中的process()方法能抛出异常,这样的话,该异常就可以被记录到日志中。

  • 监听节点存在性变化

client.checkExists().usingWatcher((CuratorWatcher) watchedEvent -> {

    System.out.println("节点存在性发生变化");

});

 

  • 监听节点的内容变化

client.getData().usingWatcher((CuratorWatcher) watchedEvent -> {

    System.out.println("节点数据内容发生变化");

});

 

  • 监听节点的子节点列表变化

client.getChildren().usingWatcher((CuratorWatcher) watchedEvent -> {

    System.out.println("节点的子节点列表发生变化");

});

 

4.4.3 代码演示

(1)创建工程

       创建一个Maven工厂,并引入一个pom依赖。


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

 

(2)代码

package com.pingan.maam.server.test;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;

import java.util.List;

public class FluentTest {
    // 指定zk集群
    private static final String CLUSTER = "192.168.100.1:2181,192.168.100.2:2181,192.168.100.3:2181";

    // 指定节点名称
    private static final String PATH = "/mylog";

    public static void main(String[] args) throws Exception {
        // 创建重试策略对象:1秒重试1次,最多重试3次
        ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3);

        // 创建客户端
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(CLUSTER)
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(3000)
                .retryPolicy(retryPolicy)
                .namespace("logs")
                .build();

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

        // 指定要创建和操作的节点,注意,其实相对于/logs节点的
        String nodePath = "/host";

        // 创建节点
        String nodeName = client.create().forPath(nodePath);
        System.out.println("新节点创建的名称为:" + nodeName);

        // 获取数据节点内容并注册watcher
        byte[] data = client.getData().usingWatcher((CuratorWatcher) watchedEvent -> {
            System.out.println(watchedEvent.getPath() + "数据内容发生改变");
        }).forPath(nodePath);
        System.out.println("节点数据内容为:" + new String(data));

        // 更新数据内容
        client.setData().forPath(nodePath, "newData".getBytes());
        // 获取更新过的数据内容
        byte[] newData = client.getData().forPath(nodePath);
        System.out.println("更新的数据内容为:" + newData);

        // 删除节点
        client.delete().forPath(nodePath);

        // 判断节点是否存在?
        Stat stat = client.checkExists().forPath(nodePath);
        Boolean isExits = true;
        if (stat == null) {
            isExits = false;
        }
        System.out.println(nodePath + "节点仍然存在吗?" + isExits);

        //创建一个初始内容为空的节点
        client.create().forPath(PATH);

        // 创建一个附带初始值的节点
        client.create().forPath(PATH, "mydata".getBytes());

        // 创建一个初始内容为空的临时节点
        client.create().withMode(CreateMode.EPHEMERAL).forPath(PATH);

        // 创建一个能自动递归创建父节点的临时节点
        client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(PATH);

        // 删除一个节点
        client.delete().forPath(PATH);

        // 删除一个节点,并递归删除其所有子节点
        client.delete().deletingChildrenIfNeeded().forPath(PATH);

        // 设置一个节点数据内容
        byte[] newDataTwo = "mydata".getBytes();
        client.setData().forPath(PATH, newData);

        // 检查节点是否存在
        client.checkExists().forPath(PATH);

        // 读取一个节点的数据内容
        byte[] dataTwo = client.getData().forPath(PATH);

        // 获取一个节点的所有子节点列表
        List<String> childrenNames = client.getChildren().forPath(PATH);

        // 监听节点的存在性变化
        client.checkExists().usingWatcher((CuratorWatcher) watchedEvent -> {
            System.out.println("节点存在性发生变化");
        });

        // 监听节点的内容变化
        client.getData().usingWatcher((CuratorWatcher) watchedEvent -> {
            System.out.println("节点数据内容发生变化");
        });

        // 监听节点的子节点列表变化
        client.getChildren().usingWatcher((CuratorWatcher) watchedEvent -> {
            System.out.println("节点的子节点列表发生变化");
        });

    }
}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值