Apache ZooKeeper - 使用原生的API操作ZK
文章目录
- 概述
- maven依赖
- 验证
- 测试基类
- ZK构造函数参数
- connectString:ZooKeeper服务器列表
- sessionTimeout:会话的超时时间, “毫秒”为单位
- watcher:事件通知处理器
- canBeReadOnly: 用于标识当前会话是否支持“read-only(只读)”模式。
- sessionId和 sessionPasswd:会话ID和会话秘钥
- CRUD
- 同步创建节点
- 修改数据
- 查询数据(不带watcher)
- 查询数据(带watcher)
- 删除数据
- 异步创建节点
概述
前面几篇系列博文我们熟悉了如何通过命令来操作ZK节点数据,下面我们来看下如何使用API来操作
主要两种方式
- 原生API
- Curator
今天我们来看下如何使用原生的API操作ZK
maven依赖
和 服务端的版本保持一致
<dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.5.8</version></dependency>
验证
接下来我们使用单元测试来验证下原生API的对ZK 数据的增删改查
测试基类
我们来写下测试基类
package com.artisan.zk.originalClient;import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.After;
import org.junit.Before;import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;@Slf4j
public abstract class StandAloneBaseTest {private static final String ZK_ADDRESS = "192.168.126.131:2181";private static final int SESSION_TIMEOUT = 30_000;private static CountDownLatch countDownLatch = new CountDownLatch(1);public static ZooKeeper getZooKeeper() {return zooKeeper;}private static ZooKeeper zooKeeper ;private static Watcher watcher = event -> {if (event.getState() == Watcher.Event.KeeperState.SyncConnected && event.getType() == Watcher.Event.EventType.None){log.info("ZK Connected");countDownLatch.countDown();}};@Beforepublic void init() throws IOException, InterruptedException {log.info("start to connect zk server: {}" , ZK_ADDRESS);zooKeeper = new ZooKeeper(ZK_ADDRESS, SESSION_TIMEOUT, watcher);log.info("connecting to....{}", ZK_ADDRESS);countDownLatch.await();}@Afterpublic void test(){try {TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}}
为了方便测试,直接在init初始化方法中创建zookeeper实例 ,不要关闭~
ZK构造函数参数
connectString:ZooKeeper服务器列表
由英文逗号分开的host:port字符串组成,每一个都代表一台ZooKeeper机器,如
host1:port1,host2:port2,host3:port3
另外,也可以在connectString中设置客户端连接上ZooKeeper后的根目录,方法是在host:port字符串之后添加上这个根目录。
例如,host1:port1,host2:port2,host3:port3/app/a
,这样就指定了该客户端连接上ZooKeeper服务器之后,所有对ZooKeeper的操作,都会基于这个根目录。
例如,客户端对/foo/bar
的操作,最终创建/app/a/foo/bar
, 这个目录也叫Chroot,即客户端隔离命名空间。
sessionTimeout:会话的超时时间, “毫秒”为单位
在ZooKeeper中有会话的概念,在一个会话周期内,ZooKeeper客户端和服务器之间会通过心跳检测机制来维持会话的有效性.
一旦在sessionTimeout时间内没有进行有效的心跳检测,会话就会失效。
watcher:事件通知处理器
ZooKeeper允许客户端在构造方法中传入一个接口 watcher (
org.apache. zookeeper.Watcher
)的实现类对象来作为默认的 Watcher事件通知处理器。
当然,该参数可以设置为null 以表明不需要设置默认的 Watcher处理器。
canBeReadOnly: 用于标识当前会话是否支持“read-only(只读)”模式。
boolean类型的参数
默认情况下,在ZooKeeper集群中,一个机器如果和集群中过半及以上机器失去了网络连接,那么这个机器将不再处理客户端请求(包括读写请
求)。
但是在某些使用场景下,当ZooKeeper服务器发生此类故障的时候,我们还是希望ZooKeeper服务器能够提供读服务(当然写服务肯定无法提供),这就是 ZooKeeper的“read-only”模式。
sessionId和 sessionPasswd:会话ID和会话秘钥
这两个参数能够唯一确定一个会话,同时客户端使用这两个参数可以实现客户端会话复用,从而达到恢复会话的效果。
具体使用方法是,第一次连接上ZooKeeper服务器时,通过调用ZooKeeper对象实例的以下两个接口,即可获得当前会话的ID和秘钥:
long getSessionId();
byte[]getSessionPasswd( );
荻取到这两个参数值之后,就可以在下次创建ZooKeeper对象实例的时候传入构造方法了
CRUD
同步创建节点
package com.artisan.zk.originalClient;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;@Slf4j
public class BaseOperationStandAloneModeTest extends StandAloneBaseTest{private static final String NODE_NAME = "/artisan-node";@Testpublic void testCreate(){try{ZooKeeper zooKeeper = getZooKeeper();String s = zooKeeper.create(NODE_NAME,"artisan-node-value".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);log.info("create persistent node {} , result {}" , NODE_NAME, s );}catch (Exception e){log.error("create Exception {}", e.getMessage());}}
}
修改数据
@SneakyThrows@Testpublic void testSetData() {// 修改前数据Stat stat = new Stat();byte[] data = getZooKeeper().getData(NODE_NAME, null, stat);log.info("data before change: " + new String(data));int version = stat.getVersion();log.info("data version {} " , version);// 修改数据Stat newStat = getZooKeeper().setData(NODE_NAME, "ARTISAN - NEW-SET-DATA".getBytes(), version);log.info("new stat version info {} " , newStat.getVersion());log.info("data after change: {} " , new String(getZooKeeper().getData(NODE_NAME, null, newStat)));}
查询数据(不带watcher)
@SneakyThrows@Testpublic void testGetWithOutWatch(){byte[] data = getZooKeeper().getData(NODE_NAME, null, null);log.info("data {}" , new String(data));}
查询数据(带watcher)
@SneakyThrows@Testpublic void testGetWithWatch(){Watcher watcher = new Watcher() {@Overridepublic void process(WatchedEvent event) {// 监听NodeDataChanged事件if (event.getPath() != null && event.getPath().equals(NODE_NAME)&& event.getType() == Watcher.Event.EventType.NodeDataChanged){log.info("path {} changed watched " , NODE_NAME);// 监听一旦触发就会失效,因此需要重新监听try {byte[] data = getZooKeeper().getData(NODE_NAME, this, null);log.info("监听触发后的操作-- data: {}",new String(data));} catch (Exception e) {log.info("getData Error {} " , e.getMessage());}}}};// 获取节点数据byte[] data = getZooKeeper().getData(NODE_NAME, watcher, null);log.info("data {}" , new String(data));}
因为监听的是NodeDataChanged事件,因此我们再去调用修改数据的方法,或者在客户端手动修改数据
观察testGetWithWatch的日志
zk里查看数据
删除数据
@SneakyThrows@Testpublic void testDelete(){// if the given version is -1, it matches any node's versions// -1 代表匹配所有版本,直接删除// 任意大于 -1 的代表可以指定数据版本删除getZooKeeper().delete(NODE_NAME,-1);}
查看客户端,已经删除
异步创建节点
@SneakyThrows@Testpublic void testCreateAsyn(){getZooKeeper().create(NODE_NAME, "DATA_VALUE".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT,(rc, path, ctx, name) -> {String currentThreadName = Thread.currentThread().getName();log.info("currentThreadName {} , rc {} , path {} , ctx {} , name {} " , currentThreadName, rc , path ,ctx ,name );}, "ARTISAN");byte[] data = getZooKeeper().getData(NODE_NAME, null, null);log.info("data {}" , new String(data));}
EventThread创建的节点 ,而非当前线程
行了 基本操作就这些,下篇继续
Apache ZooKeeper - 使用原生的API操作ZK相关推荐
- Apache ZooKeeper - 使用原生的API操作ZK_ACL权限
文章目录 Pre Code 创建world模式的节点 使用授权模式创建节点 使用授权模式获取节点数据 Pre Apache ZooKeeper - ZK的ACL权限控制( Access Control ...
- Java API操作ZK node
创建会话 建立简单连接 /*** 测试创建Zk会话* Created by liuhuichao on 2017/7/25.*/ public class ZooKeeper_Constructor_ ...
- Apache ZooKeeper - 使用Apache Curator操作ZK
文章目录 原生ZK API VS Curator Curator 概述 Maven依赖 会话创建 静态工厂方式创建会话 使用 fluent 风格创建会话 创建节点 protection 模式 ,规避僵 ...
- Zookeeper_原生API操作(一)
讲了zookeeper的简单的介绍,以及环境搭建,还有zkClient的使用,基本上很简单,作为HelloWorld,今天继续往下走,既然已经把简介和环境搭建完了,然后一会来说说配置,配置也没有什么说 ...
- Zookeeper_原生API操作(二)
在有curator这个框架之前的时候,然后zookeeper怎么去实现分布式锁,就是利用刚才的那种方案,就是可以去实现,你会有各种各样的疑问,你刚才讲的设计是得先get一下,你不如直接create,因 ...
- 2021年大数据ZooKeeper(五):ZooKeeper Java API操作
目录 ZooKeeper Java API操作 引入maven坐标 节点的操作 ZooKeeper Java API操作 这里操作Zookeeper的JavaAPI使用的是一套zookeeper客户端 ...
- Apache ZooKeeper - 使用源码启动ZK集群模式
文章目录 Pre 配置总览 端口说明 Node 1 [zoo1.cfg ] [myid] Node 2 [zoo2.cfg ] [myid] Node 3 [zoo3.cfg ] [myid] 启动集 ...
- Apache ZooKeeper - ZK的内存数据 + 持久化事务日志 + 数据快照 初探
文章目录 内存数据 源码实现 事务日志 配置项 查看事务日志数据 LogFormatter 写入日志的优化 (预分配) 数据快照 查看数据快照数据 SnapshotFormatter 事务日志 VS ...
- Apache ZooKeeper - ZK的ACL权限控制( Access Control List )
文章目录 概述 权限模式(Scheme) 口令验证 范围验证 Super权限模式 授权对象(ID) 权限信息(Permission) ACL相关命令 跳过ACL检测 实操ACL 生成授权ID 方式一 ...
最新文章
- LeetCode-198. 打家劫舍
- delphi 数据 上移 下移_脑图-数据库查询优化器的艺术
- Linux 下 Redis 安装详解
- Linux的MySQL不能远程访问
- Linux创建线程读取双口数据,linux环境下读写一次双口ram尽然要十几个毫秒。(附驱动代码)...
- malloc 源码_【C++学习笔记(九)】之 new运算符的使用/ new 与 malloc的异同(附代码,详细注释)...
- oracle控制文件的损坏或完全丢失的恢复办法
- 六十、第一个SpringBoot的 helloworld程序
- android启用hdcp_如何在Android上启用优先收件箱(和设置仅重要通知)
- python正则表达式代码_python正则表达式的使用(实验代码)
- linux sed 笔记
- 如果因为断电等导致文件损坏的系统无法开启的解决办法(鸟哥私房菜)
- 南瑞科技服务器型号,南瑞--NSC通讯概述
- 计算机应用基础试卷分析报告,计算机应用基础试卷分析.pdf
- FLV、AAC、AVC封装格式分析
- office2003无法正常安装卸载问题解决
- 为什么安监控需要公网ip_关于花生壳公网版和内网版应用场合的一些说明
- 申请亚马逊AWS一年免费服务器
- linux运行igv报错,IGV 哐当就不能用了,除了换台电脑还能怎么办?
- GPT-4王者加冕!读图做题性能炸天,凭自己就能考上斯坦福
热门文章
- android 获取url中的参数
- C++多继承(多重继承)详解(一)
- TC工具后台模式_聊天能赚钱?来聊后台批量添加账号,伪装女性聊天赚钱内幕...
- 深度学习核心技术精讲100篇(三十八)-滴滴司机调度系统实践
- 用Tableau画3D模型之四(放弃篇)
- Python零碎知识(1):strip lstrip rstrip使用方法
- pycharm安装怎么选_客厅窗帘怎么选 客厅窗帘怎么安装好看
- Java基础部分自测题(持续更新)
- Jupyter Notebook 代码自动补全功能
- Python编程基础:第五十二节 高阶函数High Order Functions