Zookeeper JavaAPI操作(Curator API常用操作)

构建项目

zk版本:3.5.7,引入4.0.0的curator版本,Curator依赖的版本只能比zookeeper依赖的版本高。

Curator简单介绍

Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等等,现在是Apache的开源项目。
Curator封装了很多功能(分布式锁、leader选举、分布式队列、共享计数器等等),更加简单易用

Curator对比zookeeper原生API

  • 原生API的超时重连,需要手动操作,而Curator封装了很多重连策略,自动重连
  • 原生API不支持递归创建节点,Curator可以递归创建节点
  • 是对原生API的进一步封装,功能更多,更容易使用
  • Curator 是Fluent的API风格(依赖于方法链、提高代码的易读性)

pom文件引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>curator-zk</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- https://mvnrepository.com/artifact/junit/junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version><scope>test</scope></dependency><!--        curator--><!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.0.0</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.curator/curator-recipes --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.0.0</version></dependency><!--        日志--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

log4j.properties(resource目录下)

### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=off, stdout
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH/:mm/:ss}]-%5p %c(line/:%L) %x-%m%n

建立连接

package com.tang.curator;import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.junit.Test;public class CuratorTest {/*** 建立连接*/@Testpublic  void testConnect() {//重试策略ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(3000,10);//第一种创建方式:通过构造器构造CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", 60*1000, 15*1000, retryPolicy);//第二种创建方式:通过builder模式链式编程client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(60*1000).connectionTimeoutMs(15*1000).retryPolicy(retryPolicy).namespace("zkProject").build();//开启连接client.start();}
}
构造参数意义
connectString连接url,集群用逗号分割 ,127.0.0.1:2181,127.0.0.1:2182
sessionTimeoutMs会话超时时间(建立连接后,会话断开的重连时间) 单位:毫秒,默认60秒
connectionTimeoutMs连接超时时间 单位:毫秒,默认15秒
retryPolicy重试策略
namespace默认一个根目录,以后的所有创建都会在此目录下进行

RetryPolicy相关(重试连接策略)

在这里插入图片描述
在这里插入图片描述

ExponentialBackoffRetry‌

特点‌:采用指数退避算法来实现重试机制。每次重试失败后,等待时间间隔会逐渐增加,直到达到最大重试次数或者重试成功为止。这种策略适用于需要逐渐延长重试间隔以减少对系统的冲击,同时确保最终能够成功连接的场景。
‌实现‌:ExponentialBackoffRetry实现了RetryPolicy接口,并提供了一些构造方法来设置重试的参数,如最大重试次数、初始等待时间、最大等待时间等‌

RetryNTimes‌

特点‌:简单地重试N次,不考虑重试之间的时间间隔。这种策略适用于希望快速重试且对重试次数有明确限制的场景。
‌实现‌:通过指定重试次数N来实例化该策略,当重试次数达到N时停止重试‌

RetryOneTime‌

特点‌:只重试一次,即如果初次尝试失败,则进行一次重试,然后停止。这种策略适用于对重试要求不高的场景,或者作为其他策略的补充。
‌注意‌:虽然这种策略较为简单,但在某些情况下可能仍然有用,特别是当希望快速失败而不是无限重试时。

RetryUntilElapsed‌

特点‌:在指定的总时间内不断重试,直到成功或时间耗尽。这种策略适用于对时间有明确要求,且希望在这段时间内尽可能多地尝试连接的场景。
‌实现‌:需要指定一个最长等待时间,在这段时间内会不断尝试重试,直到成功或时间到期‌

RetryForever‌

特点‌:永远重试,直到成功为止。这种策略适用于对连接成功有极高要求,且不介意无限重试的场景。
注意‌:在实际应用中应谨慎使用此策略,以避免因无限重试而导致的资源耗尽或其他问题‌

添加节点

有四种添加节点的方式:

  1. 基本创建:create().forPath()
  2. 创建带数据的节点:create().forPath(path,value)
  3. 设置节点类型:create().withMode().forPath()
  4. 创建多节点(父节点不存在会报错,创建时需要调用:creatingParentContainersIfNeeded方法)

节点类型是一个CreateMode的枚举,有以下四种类型:

节点名称枚举解释
持久节点‌Persistent节点创建后,会一直保存在ZooKeeper中,直到被明确删除
持久顺序节点PersistentSequential在创建子节点时,ZooKeeper会自动为节点名称添加一个数字后缀,以保证子节点的创建顺序
临时节点Ephemeral节点的生命周期与创建它的会话绑定在一起,会话结束后,节点也会被自动删除
‌临时顺序节点‌EphemeralSequential与持久顺序节点类似,但节点的生命周期是临时的,与会话绑定
/*** 创建节点*/@Testpublic void create() throws Exception {//1.基本创建//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储client.create().forPath("/test");//2.创建带数据的节点,如果这里的path还是/test就会报错client.create().forPath("/test1","test".getBytes());}@Testpublic void testCreate2() throws Exception {// 设置节点类型 (默认:持久化)String path = client.create().withMode(CreateMode.EPHEMERAL) // 设置临时模式.forPath("/app3");//输出path为/app3System.out.println(path);}@Testpublic void testCreate3() throws Exception {// 创建多节点String path = client.create().creatingParentContainersIfNeeded() // 父节点不存在,则创建父节点.forPath("/app4/p2");//输出path为/app4/p2System.out.println(path);}

查询节点

  1. 查询数据:client.getData().forPath()
  2. 查询子节点:client.getChildren().forPath()
  3. 查询节点信息状态: client.getData().storingStatIn(stat).forPath()
 /*** 查询节点* @throws Exception*/@Testpublic void testGet() throws Exception {//1.查询数据:getbyte[] data = client.getData().forPath("/app1");System.out.println("1.查询数据:"+new String(data));// 2.查询子节点:lsList<String> path  = client.getChildren().forPath("/app4");System.out.println("2."+path);//3.查询节点状态信息:ls -sStat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app1");System.out.println("3."+stat.toString());}

修改节点

  1. 基本数据修改: client.setData().forPath()
  2. 根据版本修改:client.setData().withVersion().forPath()
    一般使用第二种修改方式,version 是通过查询出来的,目的是为了让其他客户端不干扰我修改(原子性操作)
	/*** 1.基本修改数据:.setData().forPath()* * @throws Exception*/@Testpublic void testSet() throws Exception {client.setData().forPath("/test","MarryChristmas".getBytes());}/***2.根据版本修改*  version 是通过查询出来的,目的是为了让其他客户端不干扰我(原子性操作)* @throws Exception*/@Testpublic void testSetForVersion() throws Exception {int version = 0;Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/test");version = stat.getVersion();client.setData().withVersion(version).forPath("/test","HappyNewYear".getBytes());}

删除节点

  1. 删除单个节点:client.delete().forPath()
  2. 删除带有子节点的节点: client.delete().deletingChildrenIfNeeded().forPath()
  3. 必须成功的删除:为了防止网络波动,本质就是重试:client.delete().guaranteed().forPath()
  4. 回调:inBackground()
/*** 删除节点* 1.删除单个节点* 2.删除带有子节点的节点* 3.必须成功的删除:为了防止网络抖动,本质就是重试* 4.回掉* @throws Exception*/@Testpublic void testDelete() throws Exception {client.delete().forPath("/test1");client.delete().deletingChildrenIfNeeded().forPath("/app4");client.delete().guaranteed().forPath("/app4");client.delete().guaranteed().inBackground(new BackgroundCallback() {@Overridepublic void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {System.out.println("水逆退散!");}}).forPath("/test");}

完整代码:

package com.tang.curator;import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.util.List;public class CuratorTest {private  CuratorFramework client;/*** 建立连接*/@Before//@Before表示在测试方法执行前执行@Testpublic  void testConnect() {//重试策略ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(3000,10);//第一种创建方式:通过构造器构造client = CuratorFrameworkFactory.newClient("127.0.0.1:2181", 60*1000, 15*1000, retryPolicy);//第二种创建方式:通过builder模式链式编程client = CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(60*1000).connectionTimeoutMs(15*1000).retryPolicy(retryPolicy).namespace("zkProject").build();//开启连接client.start();}/*** 创建节点*/@Testpublic void create() throws Exception {//1.基本创建//如果创建节点,没有指定数据,则默认将当前客户端的ip作为数据存储client.create().forPath("/test");//2.创建带数据的节点,如果这里的path还是/test就会报错client.create().forPath("/test1","test".getBytes());}@Testpublic void testCreate2() throws Exception {// 设置节点类型 (默认:持久化)String path = client.create().withMode(CreateMode.EPHEMERAL) // 设置临时模式.forPath("/app3");//输出path为/app3System.out.println(path);}@Testpublic void testCreate3() throws Exception {// 创建多节点String path = client.create().creatingParentContainersIfNeeded() // 父节点不存在,则创建父节点.forPath("/app4/p2");//输出path为/app4/p2System.out.println(path);}/*** 查询节点* @throws Exception*/@Testpublic void testGet() throws Exception {//1.查询数据:getbyte[] data = client.getData().forPath("/app1");System.out.println("1.查询数据:"+new String(data));// 2.查询子节点:lsList<String> path  = client.getChildren().forPath("/app4");System.out.println("2."+path);//3.查询节点状态信息:ls -sStat stat = new Stat();client.getData().storingStatIn(stat).forPath("/app1");System.out.println("3."+stat.toString());}/*** 1.基本修改数据:.setData().forPath()** @throws Exception*/@Testpublic void testSet() throws Exception {client.setData().forPath("/test","MarryChristmas".getBytes());}/***2.根据版本修改*  version 是通过查询出来的,目的是为了让其他客户端不干扰我(原子性操作)* @throws Exception*/@Testpublic void testSetForVersion() throws Exception {int version = 0;Stat stat = new Stat();client.getData().storingStatIn(stat).forPath("/test");version = stat.getVersion();client.setData().withVersion(version).forPath("/test","HappyNewYear".getBytes());}/*** 删除节点* 1.删除单个节点* 2.删除带有子节点的节点* 3.必须成功的删除:为了防止网络抖动,本质就是重试* 4.回掉* @throws Exception*/@Testpublic void testDelete() throws Exception {client.delete().forPath("/test1");client.delete().deletingChildrenIfNeeded().forPath("/app4");client.delete().guaranteed().forPath("/app4");client.delete().guaranteed().inBackground(new BackgroundCallback() {@Overridepublic void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {System.out.println("水逆退散!");}}).forPath("/test");}@Afterpublic void close() {if (client != null) {client.close();}}
}

参考博客:
https://blog.csdn.net/qq_37774171/article/details/122514318

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PDF书籍《手写调用链监控APM系统-Java版》第9章 插件与链路的结合:Mysql插件实现

本人阅读了 Skywalking 的大部分核心代码&#xff0c;也了解了相关的文献&#xff0c;对此深有感悟&#xff0c;特此借助巨人的思想自己手动用JAVA语言实现了一个 “调用链监控APM” 系统。本书采用边讲解实现原理边编写代码的方式&#xff0c;看本书时一定要跟着敲代码。 作者…

Kibana:LINUX_X86_64 和 DEB_X86_64两种可选下载方式的区别

最近需要在vm&#xff08;操作系统是 Ubuntu 22.04.4 LTS&#xff0c;代号 Jammy。这是一个基于 x86_64 架构的 Linux 发行版&#xff09;上安装一个7.17.8版本的Kibana&#xff0c;并且不采用docker方式。 在下载的时候发现有以下两个选项&#xff0c;分别是 LINUX_X86_64 和 …

CMake 构建项目并整理头文件和库文件

本文将介绍如何使用 CMake 构建项目、编译生成库文件&#xff0c;并将头文件和库文件整理到统一的目录中以便在其他项目中使用。 1. 项目结构 假设我们正在构建一个名为 rttr 的开源库&#xff0c;初始的项目结构如下&#xff1a; D:\WorkCode\Demo\rttr-master\|- src\ …

AIA - IMSIC之二(附IMSIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 ​​​​​​​通过IMSIC接收外部中断的CSR 软件通过《AIA - 新增的CSR》描述的CSR来访问IMSIC。 machine level 的 CSR 与 IMSIC 的 machine level interrupt file 可相互互动;而 supervisor level 的 CSR…

Vue单页应用的配置

前面通过几篇文章了解并掌握了 Vue 项目构建及运行的前期工作 。接下来我们可以走进 Vue 项目的内部&#xff0c;一探其内部配置的基本构成。 1. 路由配置 由于 Vue 这类型的框架都是以一个或多个单页构成&#xff0c;在单页内部跳转并不会重新渲染 HTML 文件&#xff0c;其路…

CocosCreator-引擎案例-TS:spine

工程1&#xff1a;LoadSpine&#xff1a;简单加载spine资源 建立工程&#xff0c;在层级上建立一个空对象&#xff0c;改名spine 在spine上添加spine组件&#xff1a; 添加组件>渲染组件>spine 在spine上挂上脚本loadspine onLoad () {cc.resources.load(loadSpine/ali…

使用FreeNAS软件部署ISCSI的SAN架构存储(IP-SAN)练习题

一&#xff0c;实验用到工具分别为&#xff1a; VMware虚拟机&#xff0c;安装教程&#xff1a;VMware Workstation Pro 17 安装图文教程 FreeNAS系统&#xff0c;安装教程&#xff1a;FreeNAS-11.2-U4.1安装教程2024&#xff08;图文教程&#xff09; 二&#xff0c;新建虚…

【ANGULAR网站开发】初始环境搭建

1. 初始化angular项目 1.1 创建angular项目 需要安装npm和nodejs&#xff0c;这边不在重新安装 直接安装最新版本的angular npm install -g angular/cli安装指定大版本的angular npm install -g angular/cli181.2 启动angular 使用idea启动 控制台启动 ng serve启动成功…

【再谈设计模式】享元模式~对象共享的优化妙手

一、引言 在软件开发过程中&#xff0c;我们常常面临着创建大量细粒度对象的情况&#xff0c;这可能会导致内存占用过高、性能下降等问题。享元模式&#xff08;Flyweight Pattern&#xff09;就像是一位空间管理大师&#xff0c;它能够在不影响功能的前提下&#xff0c;有效地…

Milvus×EasyAi:如何用java从零搭建人脸识别应用

如何从零搭建一个人脸识别应用&#xff1f;不妨试试原生Java人工智能算法&#xff1a;EasyAi Milvus 的组合拳。 本文将使用到的软件和工具包括&#xff1a; EasyAi&#xff1a;人脸特征向量提取Milvus&#xff1a;向量数据库用于高效存储和检索数据。 01. EasyAi&#xff1a;…

NS3学习——tcpVegas算法代码详解(2)

NS3学习——tcpVegas算法代码详解&#xff08;1&#xff09;-CSDN博客 目录 4.TcpVegas类中成员函数 (5) CongestionStateSet函数 (6) IncreaseWindow函数 1.检查是否启用 Vgas 2.判断是否完成了一个“Vegas 周期” 2.1--if&#xff1a;判断RTT样本数量是否足够 2.2--e…

GitLab 将停止为中国区用户提供服务,60天迁移期如何应对? | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 GitLab作为一个广受欢迎的开源代码托管平台&#xff0c;近期宣布将停止服务中国大陆、澳门和香港地区的用户提供服务。根据官方通知&#x…

华为实训课笔记 2024 1223-1224

华为实训 12/2312/24 12/23 [Huawei]stp enable --开启STP display stp brief --查询STP MSTID Port Role STP State Protection 实例ID 端口 端口角色 端口状态 是否开启保护[Huawei]display stp vlan xxxx --查询制定vlan的生成树计算结…

《Java源力物语》-3.空值猎手

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” \quad 夜色渐深&#xff0c;在一处偏僻小径上&#xff0c;月光透过浓密的源力云层&#xff0c;在地面上投下斑驳的光影。String正独自练习着刚从…

科技云报到:人工智能时代“三大件”:生成式AI、数据、云服务

科技云报到原创。 就像自行车、手表和缝纫机是工业时代的“三大件”。生成式AI、数据、云服务正在成为智能时代的“新三大件”。加之全球人工智能新基建加速建设&#xff0c;成为了人类社会数字化迁徙的助推剂&#xff0c;让新三大件之间的耦合越来越紧密。从物理世界到数字世…

hiprint结合vue2项目实现静默打印详细使用步骤

代码地址是&#xff1a;vue-plugin-hiprint: hiprint for Vue2/Vue3 ⚡打印、打印设计、可视化设计器、报表设计、元素编辑、可视化打印编辑 本地安装包地址&#xff1a;electron-hiprint 发行版 - Gitee.com 1、先安装hipint安装包在本地 2、项目运行npm&#xff08;socket.…

CUDA各种内存和使用方法

文章目录 1、全局内存2、局部内存3、共享内存3.1 静态共享内存3.2 动态共享内存 4、纹理内存5、常量内存6、寄存器内存7、用CUDA运行时API函数查询设备CUDA 错误检测 1、全局内存 特点&#xff1a;容量最大&#xff0c;访问延时最大&#xff0c;所有线程都可以访问。 线性内存…

Chapter 03 复合数据类型-1

1.列表 Python内置的一种有序、可变的序列数据类型&#xff1b; 列表的定义&#xff1a; [ ]括起来的逗号分隔的多个元素组成的序列 列表对象的创建&#xff1a; &#xff08;1&#xff09;直接赋值 >>> list1 []#创建一个空列表赋值给list1 >>> list…

【后端】LNMP环境搭建

长期更新各种好文&#xff0c;建议关注收藏&#xff01; 本文近期更新完毕。 LNMPlinuxnginxmysqlphp 需要的资源 linux服务器 web服务软件nginx 对应的语言编译器代码文件 数据库mysql安装 tar.gz包或者命令行安装 进入root&#xff1a; sodu 或su mkdir path/{server,soft}…

基于PyQt5的UI界面开发——多界面切换

介绍 最初&#xff0c;因为课设的缘故&#xff0c;我只是想做一个通过按键进行切面切换而已&#xff0c;但是我看网上资料里面仅是语焉不详&#xff0c;让我困惑的很&#xff0c;但后面我通过摸索才发现这件事实在是太简单了&#xff0c;因此我想要记录下来。 本博客将介绍如…