使用Java访问ZK

这篇笔记记录如何通过Java代码操作ZK集群上的数据。通过Java代码的操作方式和客户端命令行参数其实基本是对应的,非常简单,这里就简单举几个例子。

引入Maven依赖

其实,ZK客户端包就一个org.apache.zookeeper,但是它的日志系统比较烦人,ZK的客户端包依赖了log4j,但我们现在基本用的都是slf4j+logback的方式,我们需要把log4j和slf4j从ZK客户端包中排除,再引入我们的日志系统。

<dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.4.10</version>
  <exclusions>
    <exclusion>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>log4j-over-slf4j</artifactId>
  <version>1.7.25</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.25</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>1.2.3</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-access</artifactId>
  <version>1.2.3</version>
</dependency>
<dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.2.3</version>
</dependency>

注意:我当前使用的版本是有这个问题的,如果后续更新了新版本,情况可能会不同。

代码演示

创建节点

下面代码创建一个ZK节点,并指定数据:

@Test
public void createNode() throws Exception {
  ZooKeeper zkClient = new ZooKeeper(connStr, sessionTimeout, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    }
  });
  String path = zkClient.create("/mynode", "hello,world".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  System.out.println(path);
}

注意create方法参数,分别是节点路径,数据(byte[]类型),访问权限(Ids.OPEN_ACL_UNSAFE,即任何人都可以访问),节点类型(CreateMode.PERSISTENT即非临时节点)

获取节点值

@Test
public void getNodeValue() throws Exception {
  ZooKeeper zkClient = new ZooKeeper(connStr, sessionTimeout, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
    }
  });
  byte[] data = zkClient.getData("/mynode", false, null);
  String dataStr = new String(data);
  System.out.println(dataStr);
}

上面代码,我们使用getData()获取节点值,第一个参数是节点的路径,第二个参数表示是否监听,第三个参数是节点状态,如果用不到,传null即可。

监听节点变化

@Test
public void listenNodeChange() throws Exception {
  ZooKeeper zkClient = new ZooKeeper(connStr, sessionTimeout, new Watcher() {
    @Override
    public void process(WatchedEvent event) {
      System.out.println("监听触发");
    }
  });
  List<String> children = zkClient.getChildren("/", true);
  System.out.println(children);
  Thread.sleep(Integer.MAX_VALUE);
}

上面代码中,我们通过getChildren的第二个参数指定使用监听,这和在zkCli.sh中的命令指定watch参数是一样的,监听的回调函数是new Watcher() { ... }中指定的逻辑,其中的逻辑会在新线程中运行,因此我们测试时要注意主线程先别结束。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap