ZooKeeper Java 客户端连接—原生 API

第二部分我们使用命令行讲解了Zookeeper的部分使用,除此之外ZooKeeper还提供了Java和C客户端,我们可以通过使用代码的方式连接和操作ZooKeeper服务。Zookeeper为Java连接提供了zookeeper包用于连接ZooKeeper服务,除此之外还有封装了zookeeper的zkClient客户端和curator客户端。

Maven依赖

Zookeeper官方为我们提供了客户端用于使用Java连接和操作Zookeeper服务器,我们需要引入的Maven如下:

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

ZooKeeper服务连接

使用原生Zookeeper连接Zookeeper服务比较简单,只需要创建ZooKeeper对象即可,如下为ZooKeeper的连接例子。我们只使用ZooKeeper的构造方法创建ZooKeeper实例即可。代码如下:

public static ZooKeeper getZookeeper() throws IOException {
    if(zooKeeper == null) {
        synchronized (ZooKeeperUtil.class) {
            if(zooKeeper == null) {
                zooKeeper = new ZooKeeper(host, timeout, null);
            }
        }
    }
    return zooKeeper;
}

ZooKeeper为我们提供了四个构造方法用于创建ZooKeeper实例连接ZooKeeper服务器,源码,部分源码如下,也是我们上面代码使用的构造方法,如果有兴趣则可以自己查看更多源码:

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException {
//connectString 为ZooKeeper服务器地址端口,如果多个服务则用逗
//号分割;sessionTimeout为超时时间,watcher为监听器,false为
//是否为只读。调用另一个构造方法
    this(connectString, sessionTimeout, watcher, false);
}

ZooKeeper CURD API

ZooKeeper实例为我们提供了操作ZooKeeper服务器的增删改查的API,这些API用起来非常简单,下面是对APi的一些简单介绍。

ZooKeeper提供了create方法用于创建节点数据,需要注意的是创建的时候必须先创建父节点才能创建子节点,不然会抛出异常,代码示例为源码如下所示:

zooKeeper.create("/zktest2","zktest".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
public String create(String path, byte[] data, List<ACL> acl, CreateMode createMode){
//path为节点的目录,data为节点要设置的数据 
//acl为节点所属权限,ZooKeeper为我们提供了默认的权限
//OPEN_ACL_UNSAFE,CREATOR_ALL_ACL,READ_ACL_UNSAFE
//CreateMode 为节点类型,最新版本的Zookeeper支持四种节点类型
//PERSISTENT,PERSISTENT_SEQUENTIAL,EPHEMERAL,
//EPHEMERAL_SEQUENTIAL;分别代表持久性节点,持久性有序节点,临时
//节点,临时有序节点
......
}
//除上面的方法之外,ZooKeeper还未我们提供了一个create方法可以传入
//一个回调和上下文参数。如下所示:StringCallback 为回调,ctx为上下
//文参数,该参数可以在回调中取到
public void create(String path, byte[] data, List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx){
    ......
}

ZooKeeper提供了setData方法用于更改节点数据,更新节点数据的时候必须有节点存在才会更新,否则会抛出异常。代码示例为源码如下所示:

zooKeeper.setData("/zktest2","zktest2".getBytes(), 0);
public Stat setData(String path, byte[] data, int version){
// path为要修改的节点路径
// data 为要修改的值
// version为要修改的节点路径的版本号,版本号错误会抛出异常
}
//与create类似,新增回调和上下文内容字段,该字段可以在回调中取到
public void setData(String path, byte[] data, int version, StatCallback cb, Object ctx){
    ......
}

ZooKeeper提供了Delete方法用于删除节点数据,需要注意的是删除的时候,必须要删除子节点,才能删除父节点,否则会抛出异常。代码示例为源码如下所示:

zooKeeper.delete("/zktest2", 0);
//path为要删除的节点,必须先删除子节点,才能删除父节点
// version为版本号,版本号不对也会抛出异常
public void delete(String path, int version){
    ......
}
//与create和setData类似新增了 voidCallback回调和ctx参数,ctx会
//VoidCallback 回调中返回
public void delete(String path, int version, VoidCallback cb, Object ctx){
    ......
}

相对于ZooKeeper提供的增改删方法,ZooKeeper提供的查询方法较为复杂一点,它提供了getData和getChildren两个方法分别用于获取节点数据和子节点。并且我们可以这两个方法中传入一个监听器,一旦获取过的节点发生变化,会通知该监听器,监听器的内容放到下一部分讲述,如下为getData和getChildren的示例:

public  static  void queryData() throws IOException, KeeperException, InterruptedException {
    //获取ZooKeeper实例
    ZooKeeper zooKeeper = ZooKeeperUtil.getZookeeper();
    //从ZooKeeper服务器获取数据,监听器传为null,后续讲解
    String data = new String (zooKeeper.getData("/zktest2",null, null));
 }
public  static  void queryChildren() throws IOException, KeeperException, InterruptedException {
    ZooKeeper zooKeeper = ZooKeeperUtil.getZookeeper();
    //获取子节点
    List<String> childrenPath = zooKeeper.getChildren("/zktest2",null, null);
    System.out.println(childrenPath);
}

ZooKeeper监听器:

Zookeeper中的监听器有两种,一种是监听ZooKeeper服务连接状态,一种用于监听节点的变化。监听服务连接状态的可以直接在ZooKeeper构造方法中传入,或者通过ZooKeeper实例的register方法传入,代码如下所示:

public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException {
    this(connectString, sessionTimeout, watcher, false);
}
public  static  void zookeeperListener() throws IOException, KeeperException, InterruptedException {
    ZooKeeper zooKeeper = ZooKeeperUtil.getZookeeper();
    zooKeeper.register(new Watcher() {
        public void process(WatchedEvent watchedEvent) {
            //watchedEvent.getType() 为none;
            //watchedEvent.getPath() 为null
            //watchedEvent.getState()为zooKeeper的连接状态
            //SyncConnected 已连接成功
            //Disconnected连接断开
            //其他状态可以查看KeeperState源码
        }
 });

除了对ZooKeeper连接的监听之外,ZooKeeper还提供了对节点的监听,可以监听节点的增删改查,它的内型由枚举类EventType控制,内型有None(-1),无 事件类型,监听ZooKeeper连接状态时返回该值;NodeCreated(1),节点创建;NodeDeleted(2),节点删除;NodeDataChanged(3),节点改变;NodeChildrenChanged(4); 子节点改变。

如下示例:在监听节点的时候,必须先获取才能监听,并且监听器是一次性的,也就是说我们获取节点时传入监听器,第一次更改节点可以监听到节点变化,第二次更改就不会在监听,想要监听必须在更改之前再次调用getData方法传入监听器。

zooKeeper.getData("/listener", new Watcher() {
    public void process(WatchedEvent watchedEvent) {
        System.out.println(watchedEvent.getType());
        System.out.println(watchedEvent.getPath());
        System.out.println(watchedEvent.getState());
    }
}, null);

上面的方法用于监听整个节点,但是不能监听到子节点的变化,因此ZooKeeper提供了用于监听子节点的变化的方法,getChildren,其用法与getData类似,这里不做介绍,可以自己用代码测试。

ooKeeper.getChildren("/listener", new Watcher() {
    public void process(WatchedEvent watchedEvent) {
        System.out.println(watchedEvent.getType());
        System.out.println(watchedEvent.getPath());
        System.out.println(watchedEvent.getState());
    }
}, null);

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值