zookeeper服务器有三种Java客户端:
1.Zookeeper,Zookeeper官方提供的原生Java客户端
2.Zkclient,在原生Zookeeper基础上进行扩展的开源第三方Java客户端
3.Curator,Netflix公司在原生zookeeper基础上开源的Java客户端
1.zookeeper客户端:
文档如下:
https://zookeeper.apache.org/doc/current/api/index.html
maven依赖
<!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper/3.5.5-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.5</version>
</dependency>
客户端连接成功时显示事件状态为SyncConnected,类型None
image.png
zookeeper的Java客户端操作zookeeper代码如下
public class ZookeeperClient01 {
private static final String ZK_ADDRESS = "127.0.0.1:2181";
private static final String ZNODE = "/ZNODE";
//到计数器,默认倒数1下
private static CountDownLatch countDownLatch = new CountDownLatch(1);
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
//创建zookeeper客户端对象
ZooKeeper zooKeeper = new ZooKeeper(ZK_ADDRESS, 500000, new Watcher() {
/**
* 观察与zookeeper有没有连接上
* 这是个异步操作,非主线程执行
* @param watchedEvent
*/
@Override
public void process(WatchedEvent watchedEvent) {
//获取事件的状态
Event.KeeperState state = watchedEvent.getState();
//获取事件类型
Event.EventType type= watchedEvent.getType();
//校验连接状态和类型,连接上的状态为SyncConnected,类型为None
if (Event.KeeperState.SyncConnected == state){
if (Event.EventType.None == type){
System.out.println("连接成功");
countDownLatch.countDown();
}
}
}
});
// 倒数计数器没有倒数完成,不能执行下面的代码.确保zookeeper对象创建成功
countDownLatch.await();
//开始操作zookeeper
//获取状态
Stat stat = zooKeeper.exists(ZNODE,false);
System.out.println(stat);
if (stat == null){
//创建节点,节点存在则创建失败
//参数 为 节点,数据,访问控制类型,创建类型(持久节点,临时节点,有序无序)
//返回值为节点路径 /ZNODE
String path = zooKeeper.create(ZNODE,"zookeeper".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("节点创建结果:"+path);
//创建子节点
//String chlidPath = zooKeeper.create(ZNODE + "/child","chlid".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
//System.out.println("子节点创建结果" + chlidPath);
}else {
//修改数据,返回该节点最新的状态
Stat updateStat = zooKeeper.setData(ZNODE, "zookeeper2".getBytes(), stat.getVersion());
//打印更新时间
System.out.println(updateStat.getMtime());
}
//获取数据 节点路径,是否进行观察,状态(将stat更新为获取的当前节点最新的状态)
byte[] bytes = zooKeeper.getData(ZNODE,false,stat);
System.out.println(new String(bytes));
List<String> children = zooKeeper.getChildren(ZNODE, false, stat);
//[CHLID]
children.forEach((String child)->{
System.out.println(children);
});
}
}
在测试的时候经常出现这个异常
Exception in thread "main" org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /ZNODE
可能是:1.防火墙的问题,关闭安装zookeeper的机器 防火墙
2.可能是在没有完全建立成功zookeeper对象时,进行了zookeeper操作,所以代码中采用了一个倒数的机制
zookeeper客户端是zookeeper自带的,编程较为繁琐,会话容易超时,重连繁琐.
节点数据是二进制,需要转换.
zookeeper客户端和服务器端的会话是异步,为了保证在做相关操作时,zookeeper客户端与服务端已经连接成功,我们需要做状态和类型校验,或者借助类似于CountDownLatch工具类.
-------------------------------------------------------------------------------------------------------------------------
2.Zkclient
在原生zookeeper基础上进行扩展的第三方Java客户端
Github:https://github.com/sgroschupf/zkclient
maven依赖
<!--https://mvnrepository.com/artifact/com.101tec/zkclient/0.11-->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
代码如下
public class ZkClientDemo {
private static final String ZK_ADDRESS = "127.0.0.1:2181";
private static final String ZNODE = "/zkclient";
public static void main(String[] args) {
//创建zookeeper连接
ZkClient client = new ZkClient(ZK_ADDRESS);
//可以重写序列化器,并在创建连接的时候指定序列化器
ZkClient mySerializerClient = new ZkClient(ZK_ADDRESS,5000,15000,new MyZkSerializer());
//判断节点是否存在
if (!client.exists(ZNODE)){
//创建持久化节点 ,初始化数据
client.createPersistent(ZNODE,"zkclient");
String chlid = client.create(ZNODE + "/chlid", "chlid", CreateMode.PERSISTENT);
System.out.println(chlid);
}else {
//修改节点数据,并返回该节点的状态
Stat znodeStat = client.writeDataReturnStat(ZNODE, "znode", -1);
System.out.println(znodeStat);
}
//获取子节点 子节点:chlid
List<String> children = client.getChildren(ZNODE);
children.forEach((String node) -> {
System.out.println("子节点:" + node);
});
//获取节点数据
String readData = client.readData(ZNODE);
Stat stat = new Stat();
//获取节点数据时更新节点状态
client.readData(ZNODE + "/chlid",stat);
System.out.println(readData);
}
}












网友评论