10、zookeeper客户端curator
curator介绍
https://blog.csdn.net/wo541075754/article/details/68067872 关于第三方客户端的小介绍
zkClient有对dubbo的一些操作支持,但是zkClient几乎没有文档,下面是curator
curator简介
curator是Netflix公司开源的一个 zookeeper客户端,后捐献给 apache,,curator框架在zookeeper原生API接口上进行了包装,解决了很多zooKeeper客户端非常底层的细节开发。提供zooKeeper各种应用场景(比如:分布式锁服务、集群领导选举、共享计数器、缓存机制、分布式队列等的抽象封装,实现了Fluent风格的APl接口,是最好用,最流行的zookeeper的客户端
原生zookeeperAPI的不足
连接对象异步创建,需要开发人员自行编码等待
连接没有自动重连超时机制
watcher一次注册生效一次
不支持递归创建树形节点
curator特点
解决
session会话超时重连watcher反复注册简化开发
api遵循
Fluent风格API
<!-- Zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.6.0</version>
<exclustions>
<exclustion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclustion>
</exclustions>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.6.0</version>
</dependency>
基础用法
public static void main(String[] args) {
// 工厂创建,fluent风格
CuratorFramework client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点
.namespace("create")
.build();
client.start();
System.out.println(client.getState());
client.close();
}
session重连策略RetryPolicy retry Policy = new RetryOneTime(3000);说明:三秒后重连一次,只重连一次
RetryPolicy retryPolicy = new RetryNTimes(3,3000);说明:每三秒重连一次,重连三次
RetryPolicy retryPolicy = new RetryUntilElapsed(1000,3000);说明:每三秒重连一次,总等待时间超过个
10秒后停止重连
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3)说明:这个策略的重试间隔会越来越长
公式:
baseSleepTImeMs * Math.max(1,random.nextInt(1 << (retryCount + 1)))baseSleepTimeMs=1000例子中的值maxRetries=3例子中的值
创建
public class curatorGettingStart {
public static CuratorFramework client;
// ids权限
public static void create1() throws Exception {
// 新增节点
client.create()
// 节点的类型
.withMode(CreateMode.EPHEMERAL)
// 节点的acl权限列表
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
// arg1:节点路径,arg2:节点数据
.forPath("/node1",new byte[0]);
}
// 自定义权限
public static void create2() throws Exception {
ArrayList<ACL> acls = new ArrayList<>();
Id id = new Id("world", "anyone");
acls.add(new ACL(ZooDefs.Perms.READ,id));
// 新增节点
client.create()
// 节点的类型
.withMode(CreateMode.EPHEMERAL)
// 节点的acl权限列表
.withACL(acls)
// arg1:节点路径,arg2:节点数据
.forPath("/node2",new byte[0]);
}
// 递归创建
public static void create3() throws Exception {
// 新增节点
client.create()
// 递归创建
.creatingParentsIfNeeded()
// 节点的类型
.withMode(CreateMode.EPHEMERAL)
// 节点的acl权限列表
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
// arg1:节点路径,arg2:节点数据
.forPath("/node2/nodex",new byte[0]);
}
// 递归创建
public static void create4() throws Exception {
// 新增节点
System.out.println(1);
client.create()
.creatingParentsIfNeeded()
// 节点的类型
.withMode(CreateMode.EPHEMERAL)
// 节点的acl权限列表
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
// 异步
.inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
System.out.println("异步创建成功");
}
})
// arg1:节点路径,arg2:节点数据
.forPath("/node2/nodex",new byte[0]);
System.out.println(2);
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
CuratorFramework client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点
.namespace("create")
.build();
client.start();
// create1();
// create2();
// create3();
create4();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
修改
public class curatorGettingStart {
public static CuratorFramework client;
public static void set1() throws Exception {
// 修改节点
client.setData()
// 版本
.withVersion(-1)
.forPath("/hadoop","hadoop1".getBytes());
}
public static void set2() throws Exception {
// 修改节点
client.setData()
.withVersion(1)
.forPath("/hadoop","hadoop2".getBytes());
}
public static void set3() throws Exception {
// 修改节点
client.setData()
.withVersion(1)
// 异步
.inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
if(curatorEvent.getType() == CuratorEventType.SET_DATA)
System.out.println(curatorEvent.getPath()+ " " +curatorEvent.getType());
}
})
.forPath("/hadoop","hadoop3".getBytes());
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
.namespace("update")
.build();
client.start();
// set1();
set2();
// set3();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
删除
public class curatorGettingStart {
public static CuratorFramework client;
public static void delete1() throws Exception {
// 删除节点
client.delete()
.forPath("node1");
}
public static void delete2() throws Exception {
// 删除节点
client.delete()
// 版本
.withVersion(1)
.forPath("node2");
}
public static void delete3() throws Exception {
// 删除节点
client.delete()
// 递归删除
.deletingChildrenIfNeeded()
.withVersion(-1)
.forPath("node3");
}
public static void delete4() throws Exception {
// 删除节点
client.delete()
.withVersion(-1)
// 异步
.inBackground(new BackgroundCallback() {
@Override
public void processResult(CuratorFramework curatorFramework, CuratorEvent curatorEvent) throws Exception {
if (curatorEvent.getType() == CuratorEventType.DELETE)
System.out.println(curatorEvent.getPath() + " " + curatorEvent.getType());
}
})
.forPath("node3");
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
.namespace("delete")
.build();
client.start();
// delete1();
// delete2();
// delete3();
// delete4();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
读取节点
public class curatorGettingStart {
public static CuratorFramework client;
public static void get1() throws Exception {
// 获取数据
byte[] bytes = client.getData()
.forPath("/node");
System.out.println(new String((bytes)));
}
public static void get2() throws Exception {
Stat stat = new Stat();
// 获取数据
byte[] bytes = client.getData()
.storingStatIn(stat)
.forPath("/node");;
System.out.println(new String((bytes)));
System.out.println(stat.getVersion());
System.out.println(stat.getCzxid());
}
public static void get3() throws Exception {
System.out.println(1);
// 获取数据
client.getData()
.inBackground((CuratorFramework curatorFramework, CuratorEvent curatorEvent) -> {
System.out.println(curatorEvent.getPath() + " " + curatorEvent.getType());
})
.forPath("/node");;
System.out.println(2);
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
.namespace("get")
.build();
client.start();
get1();
get2();
get3();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
读取子节点
public class curatorGettingStart {
public static CuratorFramework client;
public static void getChildren1() throws Exception {
// 获取数据
List<String> strings = client.getChildren()
.forPath("/get");
strings.forEach(System.out::println);
System.out.println("------------");
}
public static void getChildren2() throws Exception {
System.out.println(1);
// 获取数据
client.getChildren()
.inBackground((curatorFramework, curatorEvent) -> {
curatorEvent.getChildren().forEach(System.out::println);
System.out.println("------------");
})
.forPath("/get");
System.out.println(2);
System.out.println("------------");
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
// .namespace("get")
.build();
client.start();
getChildren1();
getChildren2();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
watcher
public class WatcherTest {
static CuratorFramework client;
public static void watcher1() throws Exception {
// arg1 curator的客户端
// arg2 监视的路径
NodeCache nodeCache = new NodeCache(client, "/watcher");
// 启动
nodeCache.start();
nodeCache.getListenable().addListener(new NodeCacheListener() {
@Override
// 节点变化时的回调方法
public void nodeChanged() throws Exception {
// 路径
System.out.println(nodeCache.getCurrentData().getPath() + " " + nodeCache.getCurrentData().getStat());
// 输出节点内容
System.out.println(new String(nodeCache.getCurrentData().getData()));
}
});
System.out.println("注册完成");
// 时间窗内可以一直监听
// TimeUnit.SECONDS.sleep(1000);
//关 闭
nodeCache.close();
}
public static void watcher2() throws Exception {
// arg1 客户端
// arg2 路径
// arg3 事件钟是否可以获取节点数据
PathChildrenCache pathChildrenCache = new PathChildrenCache(client, "/watcher", true);
// 启动
pathChildrenCache.start();
pathChildrenCache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
// 节点变化时的回调方法
public void childEvent(CuratorFramework curatorFramework, PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
if (pathChildrenCacheEvent != null) {
// 获取子节点数据
System.out.println(new String(pathChildrenCacheEvent.getData().getData()));
// 路径
System.out.println(pathChildrenCacheEvent.getData().getPath());
// 事件类型
System.out.println(pathChildrenCacheEvent.getType());
}
}
});
// 时间窗内可以一直监听
TimeUnit.SECONDS.sleep(1000);
//关 闭
pathChildrenCache.close();
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
// .namespace("get")
.build();
client.start();
// watcher1();
watcher2();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
事务
public class CuratorTransaction {
static CuratorFramework client;
public static void transaction() throws Exception{
/*client.inTransaction()
.create()
.withMode(CreateMode.PERSISTENT)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath("/transaction",new byte[0])
.and()
.setData()
.forPath("/setData/transaction",new byte[0])
.and()
.commit();*/
client.create()
.withMode(CreateMode.PERSISTENT)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath("/transaction",new byte[0]);
client.setData()
.forPath("/setData/transaction",new byte[0]);
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
// .namespace("get")
.build();
client.start();
transaction();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
分布式锁
InterProcessMutex:分布式可重入排它锁InterProcessReadWriteLock:分布式读写锁
public class CuratorDistributeLock {
public static CuratorFramework client;
public static void interProcessMutex() throws Exception {
System.out.println("排他锁");
// 获取一个分布式排他锁
InterProcessMutex lock = new InterProcessMutex(client, "/lock1");
// 开启两个进程测试,会发现:如果一个分布式排它锁获取了锁,那么直到锁释放为止数据都不会被侵扰
System.out.println("获取锁中");
lock.acquire();
System.out.println("操作中");
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
lock.release();
System.out.println("释放锁");
}
public static void interProcessReadWriteLock1() throws Exception {
System.out.println("写锁");
// 分布式读写锁
InterProcessReadWriteLock lock = new InterProcessReadWriteLock(client, "/lock1");
// 开启两个进程测试,观察到写写互斥,特性同排它锁
System.out.println("获取锁中");
lock.writeLock().acquire();
System.out.println("操作中");
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
lock.writeLock().release();
System.out.println("释放锁");
}
public static void interProcessReadWriteLock2() throws Exception {
System.out.println("读锁");
// 分布式读写锁
InterProcessReadWriteLock lock = new InterProcessReadWriteLock(client, "/lock1");
// 开启两个进程测试,观察得到读读共享,两个进程并发进行,注意并发和并行是两个概念,(并发是线程启动时间段不一定一致,并行是时间轴一致的)
// 再测试两个进程,一个读,一个写,也会出现互斥现象
System.out.println("获取锁中");
lock.readLock().acquire();
System.out.println("操作中");
for (int i = 0; i < 10; i++) {
TimeUnit.SECONDS.sleep(1);
System.out.println(i);
}
lock.readLock().release();
System.out.println("释放锁");
}
public static void main(String[] args) throws Exception {
// 工厂创建,fluent风格
client = CuratorFrameworkFactory.builder()
// ip端口号
.connectString("192.168.133.133:2181,192.168.133.133:2182,192.168.133.133:2183")
// 会话超时
.sessionTimeoutMs(5000)
// 重试机制,这里是超时后1000毫秒重试一次
.retryPolicy(new RetryOneTime(1000))
// 名称空间,在操作节点的时候,会以这个为父节点,可选操作
// .namespace("get")
.build();
client.start();
// interProcessMutex();
// interProcessReadWriteLock1();
interProcessReadWriteLock2();
System.out.println(client.getState() + "操作完成");
TimeUnit.SECONDS.sleep(20);
client.close();
}
}
10、zookeeper客户端curator的更多相关文章
- Zookeeper客户端Curator使用详解
Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBoot.Curator.Bootstrap写了一个可视化的Web应用: zookeep ...
- 转:Zookeeper客户端Curator使用详解
原文:https://www.jianshu.com/p/70151fc0ef5d Zookeeper客户端Curator使用详解 前提 最近刚好用到了zookeeper,做了一个基于SpringBo ...
- zookeeper(六):Zookeeper客户端Curator的API使用详解
简介 Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsEx ...
- Zookeeper客户端Curator基本API
在使用zookeper的时候一般不使用原生的API,Curator,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连.反复注册Watcher和NodeExistsExceptio ...
- Zookeeper客户端Curator的使用,简单高效
Curator是Netflix公司开源的一个Zookeeper客户端,与Zookeeper提供的原生客户端相比,Curator的抽象层次更高,简化了Zookeeper客户端的开发量. 1.引入依赖: ...
- 7.5 zookeeper客户端curator的基本使用 + zkui
使用zookeeper原生API实现一些复杂的东西比较麻烦.所以,出现了两款比较好的开源客户端,对zookeeper的原生API进行了包装:zkClient和curator.后者是Netflix出版的 ...
- 聊聊、Zookeeper 客户端 Curator
[Curator] 和 ZkClient 一样,Curator 也是开源客户端,Curator 是 Netflix 公司开源的一套框架. <dependency> <groupI ...
- Zookeeper客户端 CuratorFramework使用
CuratorFramework使用 跟着实例学习ZooKeeper的用法: Curator框架应用 ZooKeeper客户端Curator使用一 创建连接
- 八:Zookeeper开源客户端Curator的api测试
curator是Netflix公司开源的一套ZooKeeper客户端,Curator解决了很多ZooKeeper客户端非常底层的细节开发工作.包括连接重连,反复注册Watcher等.实现了Fluent ...
- Zookeeper开源客户端Curator的使用
开源zk客户端-Curator 创建会话: RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3); CuratorFramewor ...
随机推荐
- Redux和@reduxjs/toolkit的使用
1. 简介: Redux 是一种用于管理应用程序状态的 JavaScript 库.它是一个可预测的状态容器,可以用于编写 可维护和可扩展的应用程序. @reduxjs/toolkit 是一个官方提供的 ...
- 开源项目01--WTM
一.项目名称:WTM 项目所用技术栈: wtm mvvm mvc aspnetcore dotnetcore react vue layui layui-admin element-ui ncc等 项 ...
- gRPC with JWT
在 gRPC 中使用 JWT(JSON Web Tokens)进行身份验证是一种常见的做法,它可以帮助你确保请求方的身份和权限.下面是一种使用 gRPC 和 JWT 进行身份验证的步骤: 生成和签发 ...
- Prompt实战优化
1.概述 在深度学习领域,Prompt(提示语)被广泛应用于自然语言处理任务中,如文本生成.机器翻译和问答系统等.Prompt的设计对模型的性能和生成结果有着重要的影响,因此在实际应用中合理而有效地利 ...
- 收藏-即时通讯(IM)开源项目OpenIM-功能手册
OpenIM简介 OpenIM是由IM技术专家打造的开源即时通讯组件,也是目前最受欢迎的开源IM项目之一,目前github star近万.开发者通过集成OpenIM组件,并私有化部署服务端,可以将即时 ...
- SqlSugar子查询
1.基础教程 1.1 API目录 *****只查一列***** //First: SqlFunc.Subqueryable<School>().Where(s => s.Id == ...
- HarmonyOS实战[三]—可编辑的卡片交互
相关文章: HarmonyOS实战[一]--原理概念介绍安装:基础篇 HarmonyOS实战[二]-超级详细的原子化服务体验[可编辑的卡片交互]快来尝试吧 [本文正在参与"有奖征文|Harm ...
- 强烈推荐:数据标注平台doccano----简介、安装、使用、踩坑记录
1.doccano的安装与初始配置 1.1 doccano的用途 document classification 文本分类 sequence labeling 序列标注,用于命名实体识别 sequen ...
- python list 转二叉树 及遍历
from __future__ import annotations from typing import Union from collections import deque class Tree ...
- 【动态内存】C语言动态内存使用常见错误及其避免方法(初学者避雷)
C语言动态内存使用常见错误及其避免方法(初学者动态内存避雷手册) 求个赞求个赞求个赞求个赞 谢谢 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要 ...