ZooKeeper完全解析(三) 使用Java操作ZooKeeper

  在上一篇中,我们讲解了ZooKeeper的相关操作命令,链接为 ZooKeeper完全解析(二) zooKeeper命令详解,这一篇中,我们将会详细的讲解如何使用Java操作ZooKeeper。

一、引入依赖与建立连接:

  注意ZooKeeper连接池的版本最好与使用的ZooKeeper版本一致,比如使用的ZooKeeper版本为 3.4.13,那么引入的连接池依赖即为:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.13</version>
</dependency>

  建立连接的方法即为:

ZooKeeper zooKeeper = new ZooKeeper(ZooKeeperAdress, sessionTimeOut, Watcher());

其中:
  1、ZooKeeperAdress 为zooKeeper的地址,比如 127.0.0.1:2181
  2、sessionTimeOut 即为ZooKeeper等待客户端通信的最长时间,注意是ZooKeeper等待客户端,而不是客户端等待ZooKeeper,此为毫秒为单位,比如我设置此值为 10000,那么如果ZooKeeper与客户端在10秒内无法通信的话,ZooKeeper就会断开此次连接。但是如果调用zooKeeper.close()显示的关闭连接,就会立即关闭,不会等超时时间。
  3、Watcher即为一个回调接口,当发生一些事件,比如连接成功,连接失败等情况,会回调此接口。  

 

二、create(创建节点):

在zooKeeper的命令中,create为:
create [-s] [-e] [path] [value] [acl]
其中,-s为是否自动顺序创建,-e为是否为临时节点(即若创建者断连,则自动删除)。对应Java里面的方法为:

String slaveNodeNameActulPath = zooKeeper.create("/slave/slave", "".getBytes(), OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);

上述的创建中:
第一个参数为path,
第二个参数为value,
第三个参数为acl,即安全模式
第四个参数为创建的形式,.EPHEMERAL_SEQUENTIAL即对应上述的 -s ,-e 都有,即顺序的,临时的节点。

 

三、get 查看节点数据:

  可以用zooKeeper的:

public void getData(final String path, Watcher watcher,
            DataCallback cb, Object ctx) 

方法,其中:
第一个参数为 节点 的path
第二个参数为监听的回调watcher(意为如果节点的data有更新,那么会回调这个方法,不过坑爹的是,这个方法只会回调一次,所以需要每次掉完之后再重新调用,具体解决方法我下面会说)
第三个参数为此次获取的数据回调,也就是会马上回调。
第四个参数为一个预留参数,如果传入进去了,那么在DataCallback的回调里面,会再传入进来。

 1、
  先讲第三个参数回调 DataCallback 吧,这个回调是在调用getData的时候马上回调的,也就是马上会把节点里面的数据传入进来:
 

processResult(int rc, String path, Object ctx, byte data[],Stat stat)

第一个rc即为这次操作的结果,0为成功,对应的枚举为:
org.apache.zookeeper.KeeperException.Code。
第二个path即为这个getData的path。
第三个ctx即为getData中传入的第四个参数
第四个data[]即为这个节点的内容(注意节点存的都是比特数组)
第五个stat即为节点的节点信息。

 2、再说一下第二个参数回调 Watcher,这个是当节点内容有改动的时候,会调用的:
process(WatchedEvent event);
其中event里面包含了很多信息,包括这次回调的原因,为
event.getType()
因为我们只想查看因为数据更新而引起的回调,所以判断为:

if (Watcher.Event.EventType.NodeDataChanged != e.getType()) {
    return;
}

还有,因为这个数据更新只会回调一次,所以我这样通过递归的方式调用,就能一直收到回调:

    /**
     * 循环监听Get的方法
     * @param zooKeeper
     * @param path
     * @param watcher
     * @param cb
     * @param ctx
     */
    public static void loopGet(ZooKeeper zooKeeper, final String path, Watcher watcher,
                        AsyncCallback.DataCallback cb, Object ctx) {
        zooKeeper.getData(path, event -> {
            if (watcher != null) {
                watcher.process(event);
            }

            loopGet(zooKeeper, path, watcher, cb, ctx);
        }, cb, ctx);
    }

 

四、ls,ls2 查看节点的子节点:

  获取子节点与监听子节点,可以使用zooKeeper的

public List<String> getChildren(final String path, Watcher watcher,Stat stat)

 方法。

1、  其中返回的  List<String> 即为子节点的节点名(注意不是完全路径哦)
 比如 /job 中有 "job000000000"、"job0000000001" 两个节点,那么List<String>获取的即是
 "job000000000" 与 "job0000000001" 2、path即为想要获取的节点的path。
 3、watcher即为对应回调接口
 注意对应watcher中要增加判断:

    private class JobWatcher implements Watcher{

        @Override
        public void process(WatchedEvent event) {
                    if (Watcher.Event.EventType.NodeChildrenChanged != event.getType()) {
            // 非节点更新,返回
            return;
        }

        //  code ...
        }
    }

  4、节点的节点信息stat,注意这个stat我们传入进去之后,zooKeeper会将此节点的信息设置进去,具体可以看源码:

    if (stat != null) {
        DataTree.copyStat(response.getStat(), stat);
    }

    static public void copyStat(Stat from, Stat to) {
        to.setAversion(from.getAversion());
        to.setCtime(from.getCtime());
        to.setCversion(from.getCversion());
        to.setCzxid(from.getCzxid());
        to.setMtime(from.getMtime());
        to.setMzxid(from.getMzxid());
        to.setPzxid(from.getPzxid());
        to.setVersion(from.getVersion());
        to.setEphemeralOwner(from.getEphemeralOwner());
        to.setDataLength(from.getDataLength());
        to.setNumChildren(from.getNumChildren());
    }


所以可以根据这个来获取对应节点的stat信息。

 

五、stat 查看节点信息:

  可以使用zooKeeper的这个方法:

public Stat statNode(String path, Watcher watcher)
            throws KeeperException.NoNodeException 

 

六、set 设置节点数据:

可以使用zooKeeper的

public Stat setData(final String path, byte data[], int version)

方法。
  其中
1、path即为要修改的节点的path
2、data即为要设置节点的数据字节数组
3、即为指定的version,如果version大于-1,那么只有当指定节点处于此version的时候,才会被更新,如果为-1,则不管version是多少,都会更新
(注意节点在创建的时候version为0,以后每次更新version都会+1)

返回值即为Stat,里面有节点的节点信息,比如version,如果设置了一个version为0的节点,那么返回的Stat中的version即为1(因为更新过了)

 

七、delete 删除节点:

删除可以使用

public void delete(final String path, int version)

方法
其中
  path即为要删除的节点的path。
  version即为指定的version,跟set一样,当version大于-1的时候,就会只删除指定的version,当version为-1的时候,就会直接删除。

  此方法没有返回值。

 

八、分布式作业调度系统:

  下一篇中,将会讲解使用ZooKeeper来实现一个分布式作业调度系统的原理,链接为 ZooKeeper完全解析(四) 使用ZooKeeper实现分布式作业调度系统之实现原理

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值