Zookeeper后端开发工具Curator的使用 | Curator对节点的增删改查 | ACL权限控制 | 分布式锁 | 分布式计数器 | 附带最新版本下载

前言 

CuratorApache开源的一个Java工具类,通过它操作Zookeeper会变得极度舒适!

前置条件:已掌握的基本操作,比如在后台可以增减节点、ACL权限设置等。

1.Zookeeper  原生API

1.超时重连,不支持自动,需要手动操作
2.Watch注册一次后会失效
3.不支持递归创建节点

2.Zookeeper  API 升级版 Curator

1.解决watcher的注册一次就失效
2.提供更多解决方案并且实现简单 
3.提供常用的ZooKeeper工具类
4.编程风格更爽,点点点就可以了
5.可以递归创建节点等

3. 知识点

1.使用curator建立与zk的连接
2.使用curator添加/递归添加节点
3.使用curator删除/递归删除节点
4.使用curator创建/验证 ACL(访问权限列表)
5.使用curator监听 单个/父 节点的变化(watch事件)
6.基于curator实现Zookeeper分布式锁(需要掌握基本的多线程知识)
7.基于curator实现分布式计数器


由于代码量比较大,下文只会涉及到重点代码片段,从而突出重点。


准备工作

1.Maven的pom.xml中配置ZookeeperCurator的依赖

<dependency>
	<groupId>org.apache.zookeeper</groupId>
	<artifactId>zookeeper</artifactId>
	<!--建议和本地安装版本保持一致-->
	<version>3.7.0</version>
</dependency>
<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-framework</artifactId>
	<version>5.2.0</version>
</dependency>
<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-recipes</artifactId>
	<version>5.2.0</version>
</dependency>

curator-recipes:封装了一些高级特性,如:Cache事件监听Elections选举分布式锁、分布式计数器、分布式BarrierQueues队列等 

一、使用Curator建立与Zookeeper服务连接

该类会被频繁使用,故抽离为一个单独的Utils,里面只存放前后台Connect的代码。

public class ZkConnectCuratorUtil {
	final static Logger log = LoggerFactory.getLogger(ZkConnectCuratorUtil.class);
	public CuratorFramework zkClient = null; //zk的客户端工具Curator(在本类通过new实例化的是,自动start)
	private static final int MAX_RETRY_TIMES = 3; //定义失败重试次数
	private static final int BASE_SLEEP_TIME_MS = 5000; //连接失败后,再次重试的间隔时间 单位:毫秒
	private static final int SESSION_TIME_OUT = 1000000; //会话存活时间,根据业务灵活指定 单位:毫秒
	private static final String ZK_SERVER_IP_PORT = "192.168.31.216:2181";//Zookeeper服务所在的IP和客户端端口
	private static final String NAMESPACE = "workspace";//指定后,默认操作的所有的节点都会在该工作空间下进行
	
	//本类通过new ZkCuratorUtil()时,自动连通zkClient
	public ZkConnectCuratorUtil() {
		RetryPolicy retryPolicy = new RetryNTimes(MAX_RETRY_TIMES, BASE_SLEEP_TIME_MS);//首次连接失败后,重试策略
		zkClient = CuratorFrameworkFactory.builder()
				//.authorization("digest", "root:root".getBytes())//登录超级管理(需单独配)
				.connectString(ZK_SERVER_IP_PORT)
				.sessionTimeoutMs(SESSION_TIME_OUT)
				.retryPolicy(retryPolicy)
				.namespace(NAMESPACE).build();
		zkClient.start();
	}
	public void closeZKClient() {
		if (zkClient != null) {
			this.zkClient.close();
		}
	}
 
	public static void main(String[] args) {
		ZkConnectCuratorUtil zkUtil=new ZkConnectCuratorUtil();
		boolean ifStarted=zkUtil.zkClient.isStarted();
		System.out.println("当前客户的状态:" + (ifStarted ? "连接中" : "已关闭"));
		zkUtil.closeZKClient();
		boolean ifClose = zkUtil.zkClient.isStarted();
		System.out.println("当前客户的状态:" + (ifClose ? "连接成功" : "已关闭"));
	}
}

 下方预告:

增删改查均属前后台交互的操作,故统一写在CuratorDao.java中,统一管理。

各方法第一个入参(CuratorFramework zkClient),使用时通过如下代码获取:

ZkConnectCuratorUtil zkUtil=new ZkConnectCuratorUtil();//new的同时,zk也被启动
CuratorFramework zkClient=zkUtil.zkClient;

注: CuratorFramework相当于ZK原生API中的ZooKeeper类 


二、 使用Curator来实现节点的增删改查

1.使用curator(递归)添加节点

    //级联创建节点(原生API不支持/后台客户端也不支持,但是Curator支持)
	public static void createNodes(CuratorFramework zkClient,String nodePath,String nodeData) throws Exception {
		zkClient.create()
		.creatingParentContainersIfNeeded()//创建父节点,如果需要的话
		.withMode(CreateMode.PERSISTENT) //指定节点是临时的,还是永久的
		.withACL(Ids.OPEN_ACL_UNSAFE) //指定节点的操作权限
		.forPath(nodePath, nodeData.getBytes());
		System.out.println(nodePath+"节点已成功创建…");
	}

2.使用curator(

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个使用 Java 原生 ZooKeeper 客户端实现对 ZooKeeper 服务端的增删改查,并监听节点变化同步到另一个 ZooKeeper 的示例代码: ```java import org.apache.zookeeper.*; import org.apache.zookeeper.data.Stat; import java.io.IOException; import java.util.List; public class ZooKeeperClient implements Watcher { private static final String ZK1_ADDRESS = "zookeeper1:2181"; private static final String ZK2_ADDRESS = "zookeeper2:2181"; private static final String ZK1_PATH = "/path/to/zookeeper1"; private static final String ZK2_PATH = "/path/to/zookeeper2"; private ZooKeeper zk1; private ZooKeeper zk2; public ZooKeeperClient() throws IOException { // 连接到 zookeeper1 和 zookeeper2 zk1 = new ZooKeeper(ZK1_ADDRESS, 5000, this); zk2 = new ZooKeeper(ZK2_ADDRESS, 5000, this); } public void createNode(String path, byte[] data) throws KeeperException, InterruptedException { // 在 zookeeper1 创建节点,并将对应的数据同步到 zookeeper2 zk1.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zk2.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } public byte[] getNodeData(String path) throws KeeperException, InterruptedException { // 从 zookeeper1 获取节点的数据 return zk1.getData(path, false, null); } public void updateNode(String path, byte[] data) throws KeeperException, InterruptedException { // 更新 zookeeper1 中节点的数据,并将更新后的数据同步到 zookeeper2 zk1.setData(path, data, -1); zk2.setData(path, data, -1); } public void deleteNode(String path) throws KeeperException, InterruptedException { // 删除 zookeeper1 中的节点,并删除相应的节点zookeeper2 zk1.delete(path, -1); zk2.delete(path, -1); } public List<String> getChildren(String path) throws KeeperException, InterruptedException { // 获取 zookeeper1 中节点的子节点列表 return zk1.getChildren(path, false); } @Override public void process(WatchedEvent event) { // 监听节点变化,并将变化后的数据同步到 zookeeper2 if (event.getType() == Event.EventType.NodeDataChanged) { String path = event.getPath(); try { byte[] data = zk1.getData(path, false, null); zk2.setData(path, data, -1); } catch (KeeperException | InterruptedException e) { e.printStackTrace(); } } } public void close() throws InterruptedException { // 关闭客户端连接 zk1.close(); zk2.close(); } public static void main(String[] args) throws Exception { ZooKeeperClient client = new ZooKeeperClient(); // 创建节点并设置数据 client.createNode(ZK1_PATH, "Hello, ZooKeeper!".getBytes()); // 获取节点数据 byte[] data = client.getNodeData(ZK1_PATH); System.out.println("Node data: " + new String(data)); // 更新节点数据 client.updateNode(ZK1_PATH, "Hello, Updated ZooKeeper!".getBytes()); // 再次获取节点数据 data = client.getNodeData(ZK1_PATH); System.out.println("Updated node data: " + new String(data)); // 删除节点 client.deleteNode(ZK1_PATH); // 获取子节点列表 List<String> children = client.getChildren("/"); System.out.println("Children nodes: " + children); // 保持程序运行 Thread.sleep(Long.MAX_VALUE); client.close(); } } ``` 上述代码中,我们使用Java 原生 ZooKeeper 客户端来实现对 ZooKeeper 服务端的增删改查操作。创建了一个 `ZooKeeperClient` 类,其中包含了对应的方法用于实现对 ZooKeeper 的操作。同时,该类实现了 `Watcher` 接口,用于监听节点变化并将变化后的数据同步到另一个 ZooKeeper。 在 `main` 方法中,我们创建了一个 `ZooKeeperClient` 对象,然后调用相应的方法进行增删改查操作。同时,我们也可以看到在监听器中的 `process` 方法中处理了节点数据变化的逻辑。 注意:这只是一个简单示例,实际应用中需要根据情况处理更多的异常和错误情况。 希望这能帮助到你!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值