网站服务器做缓存,网站流,什么杭州seo公司,河源新闻最新消息文章目录 一、Zookeeper的命令行使用二、Zookeeper自带API的使用2.1 引入API2.1 API简单使用 三、Zookeeper三方客户端zkClient的使用3.1 引入依赖3.2 简单的使用案例四、Curator 客户端框架4.1 引入依赖4.2 简单使用案例 一、Zookeeper的命令行使用
ZooKeeper解压后#xff… 文章目录 一、Zookeeper的命令行使用二、Zookeeper自带API的使用2.1 引入API2.1 API简单使用 三、Zookeeper三方客户端zkClient的使用3.1 引入依赖3.2 简单的使用案例四、Curator 客户端框架4.1 引入依赖4.2 简单使用案例 一、Zookeeper的命令行使用
ZooKeeper解压后在其bin目录下包含着常用的程序例如 zkServer.sh zkCli.sh 我们使用zkCli.sh 就可以通过命令行使用Zookeeper客户端 连接zookeeper服务器 连接后输入help就可以查看所有命令和使用方式的说明了
#对于本地默认端口 则可以直接 ./zkCli.sh
# -server 指定服务地址和端口
[rootlocalhost bin]# ./zkCli.sh -server localhost:15881创建节点命令 create [-s][-e] path data acl -s或-e分别指定节点特性顺序或临时节点若不指定则创建持久节点acl⽤来进⾏权限控制。
# 创建顺序节点
[zk: localhost:15881(CONNECTED) 0] create -s /zk-test dataContent1111
Created /zk-test0000000007 # 创建临时节点临时节点在会话结束后由就会被自动删除
[zk: localhost:15881(CONNECTED) 0] create -e /zk-temp data222
Created /zk-temp# 创建永久节点
[zk: localhost:15881(CONNECTED) 2] create /zk-test-permanent data333
Created /zk-test-permanent读取节点 可以使用ls查看子节点列表使用 get 命令查看节点的内容
# 使用 ls 命令查看子节点
[zk: localhost:15881(CONNECTED) 4] ls /
[lg-PERSISTENT, zk-premament, zk-temp, zk-test-permanent, zk-test0000000000, zk-test0000000007, zookeeper]# 使用 get 命令查看节点内容 get -s 则可以附加打印节点状态信息
[zk: localhost:15881(CONNECTED) 6] get /zk-temp
data222# stat 命令查看节点状态
[zk: localhost:15881(CONNECTED) 0] stat /zk-temp
cZxid 0x30000000a
ctime Wed Jul 05 10:48:44 CST 2023
mZxid 0x30000000a
mtime Wed Jul 05 10:48:44 CST 2023
pZxid 0x30000000a
cversion 0
dataVersion 0
aclVersion 0
ephemeralOwner 0x100008d52290003
dataLength 7
numChildren 0
更新节点内容 命令set path data [version] version表示数据版本在zookeeper中节点的数据是有版本概念的这个参数⽤于指定本次更新操作是基于Znode的哪⼀个数据版本进⾏的如果版本和最新版本对不上则会更新失败这样可以防止覆盖最新写入的数据。
set /zk-premament 666删除节点 删除命令 **delete path [version]**** **如果删除的节点包含子节点那么必须先删除子节点才能删除对应节点。
二、Zookeeper自带API的使用
2.1 引入API
通过Maven引入Zookeeper提供了java客户端API依赖截至当前时间最新稳定版是 3.7.1
dependencygroupIdorg.apache.zookeeper/groupIdartifactIdzookeeper/artifactIdversion3.7.1/version
/dependency2.1 API简单使用
/*** zookeeper API 简单使用** author liuyp*/
public class ZookeeperApiSimpleTest {//是否完成连接的建立static boolean connected false;static Object lock new Object();//zookeeper实例对象static ZooKeeper zooKeeper;//定义Watcher的回调 它会收到客户端状态变化的通知也可以收到节点事件的通知static Watcher watcherProcess (watchedEvent) - {//客户端连接成功状态通知if (watchedEvent.getState() Watcher.Event.KeeperState.SyncConnected !connected) {System.out.println(watcher回调客户端连接上线);synchronized (lock) {//连接成功就通知方法返回connected true;lock.notifyAll();}}//子节点列表变化通知if (watchedEvent.getType() Watcher.Event.EventType.NodeChildrenChanged) {try {//获取最新的子节点并重新开启watchListString children zooKeeper.getChildren(watchedEvent.getPath(), true);System.out.println(watcher回调子节点变化通知 节点 watchedEvent.getPath() 的最新子节点 children);} catch (KeeperException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}//节点内容变更事件if (watchedEvent.getType() Watcher.Event.EventType.NodeDataChanged) {try {byte[] data zooKeeper.getData(watchedEvent.getPath(), false, null);System.out.println(watcher回调节点数据变化通知 节点 watchedEvent.getPath() 内容为 new String(data));} catch (KeeperException e) {e.printStackTrace();} catch (InterruptedException e) {e.printStackTrace();}}//节点删除通知if (watchedEvent.getType() Watcher.Event.EventType.NodeDeleted) {System.out.println(watcher回调节点被删除通知 watchedEvent.getPath());}};/*** demo测试入口** param args* throws IOException* throws InterruptedException* throws KeeperException*/public static void main(String[] args) throws IOException, InterruptedException, KeeperException {//同步的方式建立会话createSession();//测试创建节点先删除上一次创建的createZNode();//获取节点数据getZNodeData();//更新节点数据updateZNodeData();//删除节点deleteZNode();}/*** 一、创建会话* 创建Zookeeper会话初始化Zookeeper对象* 这里改成同步执行连接上了方法才返回*/public synchronized static void createSession() throws IOException, InterruptedException {//可以配置多个地址客户端会随机连接例如 192.168.188.130:15881192.168.188.130:15882String connectString 192.168.188.130:15881;//会话超时时间 单位是毫秒int sessionTimeout 5000;//执行结果立即返回后台异步建立连接。watcherProcesszooKeeper new ZooKeeper(connectString, sessionTimeout, watcherProcess);if (connected) {return;}//如果没执行完就让出锁进入等待状态等待出结果后被唤醒synchronized (lock) {lock.wait();}}/*** 二、创建znode*/public static void createZNode() throws KeeperException, InterruptedException {//创建一个测试的公共节点后续都在这个节点下面测试,并且给他加一个watchString testParentNodePath /zookeeperApi;if (zooKeeper.exists(testParentNodePath,false)null){zooKeeper.create(testParentNodePath, 父节点.getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}//添加监听 existgetDatazooKeeper.addWatch(testParentNodePath, AddWatchMode.PERSISTENT_RECURSIVE);zooKeeper.getChildren(testParentNodePath, true);/*** path节点创建路径* data[] :字节数组格式保存到节点的数据* acl节点ACL权限设置* createMode创建的节点类型。PERSISTENT持久节点 EPHEMERAL临时节点 还有临时顺序节点持久顺序节点*/String zNodePersistent zooKeeper.create(testParentNodePath /persistent,持久节点内容.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);String zNodeEphemeralSequential zooKeeper.create(testParentNodePath /ephemeralSequential,临时顺序节点内容.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);String zNodeEphemeral zooKeeper.create(testParentNodePath /persistentEphemeral,临时节点内容.getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);}/*** 三、获取节点数据*/public static void getZNodeData() throws KeeperException, InterruptedException {String testParentNodePath /zookeeperApi;byte[] data zooKeeper.getData(testParentNodePath, false, null);System.out.println(节点 testParentNodePath 内容为 new String(data));}/*** 三、更新节点数据*/public static void updateZNodeData() throws KeeperException, InterruptedException {String testParentNodePath /zookeeperApi;zooKeeper.setData(testParentNodePath, (新数据 Math.random()).getBytes(), -1);}/*** 四、删除znode*/public static void deleteZNode() throws KeeperException, InterruptedException {String testParentNodePath /zookeeperApi;zooKeeper.delete(testParentNodePath /persistent, -1);}}三、Zookeeper三方客户端zkClient的使用 项目地址https://github.com/sgroschupf/zkclient/issues zkClient是git上的一个开源的zookeeper的java客户端项目是对zookeeper原生API的封装使得其更易用了。 优势1. session重连 2.watch重主策 3.递归删除/添加节点 注意项目最新更新日期是2018年上生产使用前需要考虑漏洞问题。 3.1 引入依赖
!-- https://mvnrepository.com/artifact/com.101tec/zkclient --
dependencygroupIdcom.101tec/groupIdartifactIdzkclient/artifactIdversion0.11/version
/dependency
3.2 简单的使用案例
public class ZkClientTest {static CountDownLatch countDownLatch new CountDownLatch(1);public static void main(String[] args) throws InterruptedException {String testzkClientPath /zkClientAPI;//建立连接这里是同步的方式String connectString 192.168.188.130:15881;ZkClient zkClient new ZkClient(connectString);//创建节点zkClient支持递归创建没有父节点会自动创建对应的父节点zkClient.createPersistent(testzkClientPath /persistent, true);zkClient.createPersistent(testzkClientPath /persistent_readyDelete, true);//删除节点 zkClient支持自动删除节点下的子节点zkClient.delete(testzkClientPath /persistent_readyDelete, -1);//获取子节点ListString children zkClient.getChildren(testzkClientPath);System.out.println(读取节点 testzkClientPath 子节点 children);//监听事件注册//注册子节点变更事件zkClient.subscribeChildChanges(testzkClientPath, (path, childNodeList) - {System.out.println(节点子节点监听事件通知节点 path 最新子节点 childNodeList);});//注册节点数据变更事件zkClient.subscribeDataChanges(testzkClientPath, new IZkDataListener() {Overridepublic void handleDataChange(String s, Object o) throws Exception {System.out.println(节点数据监听事件通知节点 s 最新数据 o);}Overridepublic void handleDataDeleted(String s) throws Exception {System.out.println(节点数据监听事件通知节点 s 已删除);}});//写入节点数据zkClient.writeData(testzkClientPath, System.currentTimeMillis() 写入数据);//获取节点数据Object readDataResult zkClient.readData(testzkClientPath);System.out.println(读取节点数据 testzkClientPath : readDataResult);//删除节点zkClient.deleteRecursive(testzkClientPath);//阻塞最后的结束程序countDownLatch.await();}
}四、Curator 客户端框架 项目地址https://github.com/apache/curator 最开始由 netflix 在github上开源2013年成为apache顶级项目至今仍在更新 和ZkClient一样Curator解决了很多细节的底层工作包括连接重连、watch自动重新注册 节点不存在异常等并且提供了基于fluent编程风格的支持 4.1 引入依赖
!-- https://mvnrepository.com/artifact/org.apache.curator/curator-framework --
dependencygroupIdorg.apache.curator/groupIdartifactIdcurator-framework/artifactIdversion5.5.0/version
/dependency
4.2 简单使用案例
/*** Curator 是Netflix公司开源的一套ZooKeeper客户端框架* 和ZkClient一样Curator解决了很多细节的底层工作包括连接重连、watch自动重新注册* 节点不存在异常等并且提供了基于fluent编程风格的支持* author liuyp*/
public class CuratorTest {public static void main(String[] args) throws Exception {//连接信息多个连接使用逗号分隔String connectString 192.168.188.130:15881;/*** 一、发起连接** RetryPolicy重连策略 默认提供三种重连策略* 1、ExponentialBackoffRetry基于backoff的重连策略重新尝试一定次数并增加重试之间的睡眠时间* 2、RetryNTimes重连N次策略* 3、RetryForever永远重试策略** 创建连接 CuratorFramework* 1、通过CuratorFrameworkFactory.newClient 底层是CuratorFrameworkFactory.build* 2、直接通过 CuratorFrameworkFactory.build** 启动连接 CuratorFramework.start()*/int baseSleepTimeMs1000; //重试之间等待的初始时间int maxRetries5;//最大重试次数int maxSleepMs5000;//每次重试的最大睡眠时间 如果算出来的sleepMs超过这个时间则采用maxSleepMs//重试间隔时间: baseSleepTimeMs * Math.max(1, random.nextInt(1 (retryCount 1)));RetryPolicy retryPolicynew ExponentialBackoffRetry(baseSleepTimeMs,maxRetries,maxSleepMs);CuratorFramework client CuratorFrameworkFactory.builder().connectString(connectString).sessionTimeoutMs(10000).connectionTimeoutMs(5000).retryPolicy(retryPolicy).namespace(curatorAPI) //加上这个以后所有路径都是以这个路径为根路径.build();client.start();System.out.println(**********客户端已启动**********);/*** 二、创建节点* 1、默认创建内容为空的永久节点* 2、设置节点内容和原生一样使用字节数组* 3、可以使用 creatingParentsIfNeeded 方法自动创建父节点避免需要递归判断父节点是否存在*/client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath(/tempNode/create,临时节点.getBytes(StandardCharsets.UTF_8));/*** 三、测试增加监听* 1、监听类型 PERSISTENT_RECURSIVE 会循环监听注册节点和其子节点的数据变化和是否存在*/CuratorWatcher curatorWatcher(watchevent)-{System.out.println([监听通知]节点watchevent.getPath() watchevent.getType());};client.watchers().add().withMode(AddWatchMode.PERSISTENT_RECURSIVE).usingWatcher(curatorWatcher).forPath(/tempNode);client.create().forPath(/tempNode/watcher);/*** 三、读取修改节点数据 并获取状态数据*/Stat statnew Stat();byte[] bytes client.getData().storingStatIn(stat).forPath(/tempNode/create);System.out.println(读取节点数据new String(bytes,StandardCharsets.UTF_8));System.out.println(读取节点状态stat.toString());client.setData().forPath(/tempNode/create,节点/tempNode/create的新数据.getBytes(StandardCharsets.UTF_8));/*** 四、删除节点*/client.delete().forPath(/tempNode/watcher);client.delete().forPath(/tempNode/create);client.delete().forPath(/tempNode);}}