ZooKeeper之zkClient使用

本文介绍使用zkClient简化Zookeeper开发的过程。zkClient解决了原生API中的session过期问题,提供了一种易于理解的订阅机制,支持持久化的watcher,并简化了节点数据的管理和操作。文中还详细介绍了如何引入依赖并提供了示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、zkClient使用的原因
1)zookeeper原生API使用中,经常会遇到session expire这类异常,异常发生后需要进行重新连接,重新建立session,会比较麻烦
2)zookeeper的watcher机制是一次性的,如果你想订阅节点的状态变化、子节点变化等,每次在处理完变化事件之后,需要重新注册watcher。可想而知这是一件令人绝望的事情。这个特性使得在处理事件和重新加上watcher这段时间发生的节点变化将无法被感知。
3)zookeeper的API接口中,节点数据默认为二进制byte数组,如果想直接保存对象类型的数据,需要相关的序列化工作。
以上问题,zkClient可以很好的解决。
二、引入依赖
ZkClient目前有两个不同artifactId的系列。
其中最早的0.1版本maven依赖如下:

 <dependency>
     <groupId>com.github.sgroschupf</groupId>
     <artifactId>zkclient</artifactId>
     <version>0.1</version>
 </dependency>

另外一个系列为的maven依赖为:

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

源码地址

三、使用
在使用zkClient之前,需要先实例化一个zkClient对象,指定zookeeper地址以及超时时间。

        ZkClient zkClient=new ZkClient("localhost:2181",2000);

简单实例(与zookeeper原生API大同小异)

        //创建节点
        zkClient.createPersistent("/docRoot");

        //创建子节点
        zkClient.createPersistent("/docRoot/child","child data");

        //获得子节点
        List<String> childList=zkClient.getChildren("/docRoot");

        //获得子节点个数
        int childCount=zkClient.countChildren("/docRoot");

        //判断节点是否存在
        boolean flag=zkClient.exists("/docRoot/child");

        //写入节点数据
        zkClient.writeData("/docRoot/child","child data changed");

        //读取节点数据
        Object obj=zkClient.readData("/docRoot/child");

        //删除节点(删除父节点之前,需要删除其子节点)
        zkClient.delete("/docRoot/child2");

zkClient将zookeeper的watcher机制转换为一种更加容易理解的订阅形式,并且这种关系是可以保持的,而非一次性的。也就是说,当watcher使用完后,zkclient会自动再增加一个相同的watcher。zkClient将变化事件重新定义为可供订阅的三种状态,一类是子节点的变化,一类是数据的变化,还有一类是状态的变化。
1)订阅子节点状态的变化

zkClient.subscribeChildChanges("/docRoot", new IZkChildListener() {
            public void handleChildChange(String parentPath, List<String> list) throws Exception {
                String s="";
                for(String str:list){
                    s+=str+",";
                }
                System.out.println("子节点变化:"+s);
            }
        });

2)订阅节点数据的变化

zkClient.subscribeDataChanges("/docRoot", new IZkDataListener() {
    public void handleDataChange(String dataPath, Object data) throws Exception {
                System.out.println("节点数据变化:"+dataPath+"-数据:"+data.toString());
          }

    public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("节点数据删除:"+dataPath);
          }
});

3)订阅节点连接及状态的变化情况

zkClient.subscribeStateChanges(new IZkStateListener() {
            public void handleStateChanged(Watcher.Event.KeeperState keeperState) throws Exception {
        System.out.println("节点连接及状态变化:"+keeperState.name());
           }

            public void handleNewSession() throws Exception {
                System.out.println("节点Session变化。。。");
            }
});

当发生session expire异常进行重连时,由于原来的所有watcher和EPHEMERAL节点都已失效,可以在handleNewSession方法中进行相应的容错处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值