基于Curator操作ZooKeeper(一)-基本操作

版权声明: https://blog.csdn.net/Dongguabai/article/details/83026099

Java原生API操作ZooKeeper可参看:

Java原生API操作Zookeeper(一)

Java原生API操作Zookeeper(二)

相关内容:

基于Curator操作ZooKeeper(二)-Watcher操作

基于Curator操作ZooKeeper(二)-Watcher操作-补充TreeCache

Java原生操作API有以下几个不足之处:

  • 超时重连,不支持自动,必须要手动实现;
  • Watcher注册一次后只能使用一次;
  • 不支持递归创建节点;

一般企业操作ZooKeeper的客户端都会使用Apache Curator。和ZkClient一样,Curator解决了很ZooKeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等,目前已经成为了Apache的顶级项目,是全世界范围内使用最广泛的ZooKeeper客户端之一。

除了封装一些开发人员不需要特别关注的底层细节之外,Curator还在ZooKeeperAPI的基础上进行了包装,提供了一套易用性和可读性更强的Fluent风格的客户端API框架。除此之外,Curator中还提供了ZooKeeper各种应用场景(Recipe,如共享锁服务、Master选举机制和分布式计数器等)的抽象封装。

引入相关的依赖

       <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.11</version>
     
        </dependency>

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

创建客户端

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));
		
		Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

运行结果:

namespace

在3.2.0及其之后版本的ZooKeeper中,添加了“Chroot”特性,该特性允许每个客户端为自己设置一个命名空间 ( Namespace )。如果一个ZooKeeper客户端设置了Chroot,那么该客户端对服务器的任何操作,都将会被限制在其自己的命名空间下。

举个例子来说,如果我们希望为应用X分配/apps/X下的所有子节点,那么该应用可以将其所有ZooKeeper客户端的Chroot设置为/apps/X的。一旦设置了Chroot之后,那么对这个客户端来说,所有的节点路径都以/apps/X为根节点,它和ZooKeeper发起的所有请求中相关的节点路径,都将是一个相对路径—相对于/apps/X的路径。例如通过ZooKeeper客户端API创建点/test_chroot,那么实际上在服务端被创建的节点是/apps/X/test_ chroot,通过设置Chroot,我们能够将一个客户端应用与ZooKeeper服务端
的一棵子树相对应,在那些多个应用共用一个ZooKeeper集群的场景下,这对于实现不同应用之间的相互隔离非常有帮助。

节点的增删改查(同步)

新增节点

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				//namespace
				.namespace("testCRUD")
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));

		//创建节点
		String nodePath = "/dongguabai/test";
        byte[] data = "abcd".getBytes();
        cto.client.create()
                .creatingParentContainersIfNeeded()   //递归创建节点
                .withMode(CreateMode.PERSISTENT)      //节点模式
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) //ACL
                .forPath(nodePath,data); //不指定内容,则内容为空

        Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

有个要注意的地方是:

由于在ZooKeeper中规定了所有非叶子节点必须为持久节点,调用上面这个API之后,只有path参数对应的数据节点是临时节点,其父节点均为持久节点。

查询某个节点下的数据:

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.data.Stat;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				//namespace:
				.namespace("testCRUD")
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));

		//创建节点
		String nodePath = "/dongguabai/test";
        byte[] data = "abcd".getBytes();
        cto.client.create()
                .creatingParentContainersIfNeeded()   //递归创建节点
                .withMode(CreateMode.PERSISTENT)      //节点模式
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) //ACL
                .forPath(nodePath,data); //不指定内容,则内容为空

        //获取节点
        byte[] bytes = cto.client.getData().forPath(nodePath);
        System.out.println("第一次获取节点数据为:"+new String(bytes));

        Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("第二次获取节点数据为:"+new String(bytes1));
        System.out.println("获取的Stat为:"+ JsonUtil.toJSON(stat));


        Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

输出结果:

查询子节点:

数据准备:

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;

import java.util.List;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				//namespace:
				.namespace("testCRUD")
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));

        String nodePath = "/dongguabai/a";
        //创建节点
       /* byte[] data = "abcd".getBytes();
        cto.client.create()
                .creatingParentContainersIfNeeded()   //递归创建节点
                .withMode(CreateMode.PERSISTENT)      //节点模式
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) //ACL
                .forPath(nodePath,data); //不指定内容,则内容为空*/

        //获取节点
       /* byte[] bytes = cto.client.getData().forPath(nodePath);
        System.out.println("第一次获取节点数据为:"+new String(bytes));

        Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("第二次获取节点数据为:"+new String(bytes1));
        System.out.println("获取的Stat为:"+ JsonUtil.toJSON(stat));
*/
        //获取子节点
        List<String> list = cto.client.getChildren().forPath(nodePath);
        System.out.println("开始打印子节点:");
        list.forEach(result-> System.out.println(result));
        System.out.println("打印结束!");

        //修改节点
      /*  Stat stat = cto.client.setData().forPath(nodePath,"new1".getBytes());
        System.out.println("第一次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));

        Stat stat1 = cto.client.setData().withVersion(stat.getVersion()).forPath(nodePath, "new2".getBytes());
        System.out.println("第二次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));*/

        //删除节点
       /* Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("获取节点数据为:"+new String(bytes1));
        cto.client.delete()
                .guaranteed()  //防止网络抖动,只要客户端会话有效,那么Curator 会在后台持续进行删除操作,直到节点删除成功
                .deletingChildrenIfNeeded()  //如果有子节点会删除,注意除非人为删除namespace,否则namespace不会删除
                .withVersion(stat.getVersion())
                .forPath(nodePath);*/

        Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

修改节点:

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				//namespace:
				.namespace("testCRUD")
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));

        String nodePath = "/dongguabai/test";
        //创建节点
       /* byte[] data = "abcd".getBytes();
        cto.client.create()
                .creatingParentContainersIfNeeded()   //递归创建节点
                .withMode(CreateMode.PERSISTENT)      //节点模式
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) //ACL
                .forPath(nodePath,data); //不指定内容,则内容为空*/

        //获取节点
       /* byte[] bytes = cto.client.getData().forPath(nodePath);
        System.out.println("第一次获取节点数据为:"+new String(bytes));

        Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("第二次获取节点数据为:"+new String(bytes1));
        System.out.println("获取的Stat为:"+ JsonUtil.toJSON(stat));*/

        //修改节点
        Stat stat = cto.client.setData().forPath(nodePath,"new1".getBytes());
        System.out.println("第一次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));

        Stat stat1 = cto.client.setData().withVersion(stat.getVersion()).forPath(nodePath, "new2".getBytes());
        System.out.println("第二次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));



        Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

输出结果:

删除节点:

执行程序之前:

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;

public class CuratorOperator {

	public CuratorFramework client = null;
	public static final String zkServerPath = "192.168.220.135:2181,192.168.220.136:2181,192.168.220.137:2181";

	/**
	 * 实例化zk客户端
	 */
	public CuratorOperator() {
		/**
		 * 同步创建zk示例,原生api是异步的
		 * 
		 * curator链接zookeeper的重试策略:
		 *
		 * 1>ExponentialBackoffRetry【推荐】
			 * baseSleepTimeMs:初始sleep时间(ms)
			 * maxRetries:最大重试次数,超过时间就不链接了
			 * maxSleepMs:最大重试时间(ms)
		 *
		 * 给定一个初始sleep时间base5leep丁imeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
		   当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))
		   可以看出,随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,
		   maxRetries参数控制了最大重试次数,以避免无限制的重试。
		 */
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		
		/**
		 * curator链接zookeeper的策略:
		 * 2>RetryNTimes【推荐】
			 * n:重试的次数
			 * sleepMsBetweenRetries:每次重试间隔的时间(ms)
		 */
//		RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
		
		/**
		 * curator链接zookeeper的策略:
		 * 3>RetryOneTime
		 * sleepMsBetweenRetry:只重试一次,重试间隔的时间
		 */
//		RetryPolicy retryPolicy2 = new RetryOneTime(3000);
		
		/**
		 * 4>
		 * 永远重试,不推荐使用
		 */
//		RetryPolicy retryPolicy3 = new RetryForever(retryIntervalMs)
		
		/**
		 * curator链接zookeeper的策略:
		 * 5>RetryUntilElapsed
		 * maxElapsedTimeMs:最大重试时间
		 * sleepMsBetweenRetries:每次重试间隔
		 * 重试时间超过maxElapsedTimeMs后,就不再重试
		 */
//		RetryPolicy retryPolicy4 = new RetryUntilElapsed(2000, 3000);

		//创建客户端
		client = CuratorFrameworkFactory.builder()  //builder
				.connectString(zkServerPath)
				.sessionTimeoutMs(10000)  //session超时时间
				.retryPolicy(retryPolicy)  //重试策略
				//namespace:
				.namespace("testCRUD")
				.build();
		/**
		 * CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用
		   CuratorFramework的sta rt)方法来完成会话的创建。
		 */
		client.start();
	}
	
	/**
	 * 
	 * @Description: 关闭zk客户端连接
	 */
	public void closeZKClient() {
		if (client != null) {
			this.client.close();
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 实例化
		CuratorOperator cto = new CuratorOperator();
		boolean isZkCuratorStarted = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted ? "连接中" : "已关闭"));

        String nodePath = "/dongguabai/test";
        //创建节点
       /* byte[] data = "abcd".getBytes();
        cto.client.create()
                .creatingParentContainersIfNeeded()   //递归创建节点
                .withMode(CreateMode.PERSISTENT)      //节点模式
                .withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE) //ACL
                .forPath(nodePath,data); //不指定内容,则内容为空*/

        //获取节点
       /* byte[] bytes = cto.client.getData().forPath(nodePath);
        System.out.println("第一次获取节点数据为:"+new String(bytes));

        Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("第二次获取节点数据为:"+new String(bytes1));
        System.out.println("获取的Stat为:"+ JsonUtil.toJSON(stat));*/

        //修改节点
      /*  Stat stat = cto.client.setData().forPath(nodePath,"new1".getBytes());
        System.out.println("第一次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));

        Stat stat1 = cto.client.setData().withVersion(stat.getVersion()).forPath(nodePath, "new2".getBytes());
        System.out.println("第二次获取节点数据为:"+new String(cto.client.getData().forPath(nodePath)));*/

        //删除节点
        Stat stat = new Stat();
        byte[] bytes1 = cto.client.getData().storingStatIn(stat).forPath(nodePath);
        System.out.println("获取节点数据为:"+new String(bytes1));
        cto.client.delete()
                .guaranteed()  //防止网络抖动,只要客户端会话有效,那么Curator 会在后台持续进行删除操作,直到节点删除成功
                .deletingChildrenIfNeeded()  //如果有子节点会删除,注意除非人为删除namespace,否则namespace不会删除
                .withVersion(stat.getVersion())
                .forPath(nodePath);

        Thread.sleep(3000);
		
		cto.closeZKClient();
		boolean isZkCuratorStarted2 = cto.client.isStarted();
		System.out.println("当前客户的状态:" + (isZkCuratorStarted2 ? "连接中" : "已关闭"));
	}
	
}

执行结果:

判断节点是否存在:

其他相关资料:

https://blog.csdn.net/en_joker/article/details/78778917

https://www.cnblogs.com/LiZhiW/p/4926385.html?utm_source=tuicool&utm_medium=referral

猜你喜欢

转载自blog.csdn.net/Dongguabai/article/details/83026099
今日推荐