说明:本文档主要给大家介绍ZK客户端API基本操作
一、新建Java工程
1、New->Project->Java Project
填写JAVA工程名字,选择JDK版本等
2、为新建的Java工程添加外部jar包
工程名称->Java Build Path->Libraries->用户Library->新建用户Library
为用户Library添加ZK jar包,比如路径如下:
E:\depslib\zookeeper-3.4.5\lib 将此路径下的所有lib添加到新建用户库
为此Java工程准备完成,详细类似操作方法,请参考往期Java工程新建部分,这里不再赘述。
二、ZK客户端API操作
1、ZK连接通用工具类
package cn.itcast.zk.test;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper.States;
/**
* 本类是一个ZK客户端端连接工具类
* @author songjq
*
*/
public class ZkConnUtils {
/**
* ZK一直处于连接中,则进入等待,直到连接成功为止
* @param zooKeeper
* @param connectedLatch
*/
public static void waitUntilConnected(ZooKeeper zooKeeper, CountDownLatch connectedLatch) {
if (States.CONNECTING == zooKeeper.getState()) {
try {
connectedLatch.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
/**
* ZK连接监听器
* @author songjq
*
*/
static class ConnectedWatcher implements Watcher {
private CountDownLatch connectedLatch;
private ZooKeeper zk_;
ConnectedWatcher(CountDownLatch connectedLatch,ZooKeeper zk_) {
this.connectedLatch = connectedLatch;
this.zk_ = zk_;
}
/**
* 监听器回调方法
* 如果需要对某个znode进行持续监听,需要重新在回调方法中注册监听器
*/
@Override
public void process(WatchedEvent event) {
/**
* 例如在exists上注册监听器
*/
System.out.println("节点:" + event.getPath() + " 发生了事件:" + event.getType());
if (event.getState() == KeeperState.SyncConnected) {
connectedLatch.countDown();
}
}
}
/**
* 获取ZK连接实例,调用该方法即可获取可用zk连接
* @param hostports
* @param times
* @return
*/
public ZooKeeper getConnection(String hostports, int times) {
ZooKeeper zk_ = null;
try {
CountDownLatch connectedLatch = new CountDownLatch(1);
Watcher watcher = new ConnectedWatcher(connectedLatch,zk_);
zk_ = new ZooKeeper(hostports, times, watcher);
waitUntilConnected(zk_, connectedLatch);
} catch (Exception e) {
System.out.println(e);
return null;
}
return zk_;
}
static private ZkConnUtils static_;
static public ZkConnUtils Instance() {
if (static_ == null) {
static_ = new ZkConnUtils();
}
return static_;
}
}
2、ZK客户端基本操作
package cn.itcast.zk.test;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Before;
import org.junit.Test;
/**
* 本类主要实现ZK Znode节点创建、获取、修改、删除、简单监听器注册
* @author songjq
*
*/
public class ZkOperation {
private ZooKeeper zkCli = null;
@Before
public void init() throws Exception {
String hostports = "192.168.1.201:2181,192.168.1.202:2181,192.168.1.203:2181";
ZkConnUtils instance = ZkConnUtils.Instance();
zkCli = instance.getConnection(hostports, 2000);
}
/**
* 创建znode节点
* @throws IOException
* @throws KeeperException
* @throws InterruptedException
*/
@Test
public void testCreateZnode() throws IOException, KeeperException, InterruptedException {
// PERSISTENT:永久数据,客户端断开连接,数据依旧存在
String path_PERSISTENT = zkCli.create("/jackmablog", "jackma的博客".getBytes("utf-8"), Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
// EPHEMERAL:临时数据,客户端断开连接,数据自动删除
String path_EPHEMERAL = zkCli.create("/jackmablog/cloudNumber", "90".getBytes(), Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL);
System.out.println("path_PERSISTENT:" + path_PERSISTENT);
System.out.println("path_EPHEMERAL:" + path_EPHEMERAL);
//模拟客户端不断开连接,查看临时数据
//Thread.sleep(Long.MAX_VALUE);
}
/**
* 获取数据节点
* @throws KeeperException
* @throws InterruptedException
* @throws UnsupportedEncodingException
*/
@Test
public void getZnodeData() throws KeeperException, InterruptedException, UnsupportedEncodingException {
byte[] data = zkCli.getData("/jackmablog", true, null);
System.out.println("data:"+new String(data, "utf-8"));
}
/**
* 修改数据节点
* @throws Exception
*/
@Test
public void setZnodeData() throws Exception {
/*
* -1:匹配所有版本
*/
byte[] data1 = zkCli.getData("/jackmablog", true, null);
System.out.println("修改前数据:"+new String(data1, "utf-8"));
zkCli.setData("/itheima", "伟大的云计算".getBytes("utf-8"), -1);
byte[] data2 = zkCli.getData("/jackmablog", true, null);
System.out.println("修改后数据:"+new String(data2, "utf-8"));
//模拟zk客户端不断开连接,监视数据变化
//Thread.sleep(Long.MAX_VALUE);
}
/**
* 删除Znode
* @throws InterruptedException
* @throws KeeperException
*/
@Test
public void deleteZnode() throws InterruptedException, KeeperException {
System.out.println((zkCli.exists("/jackmablog", true)==null)?"/jackmablog不存在":"/jackmablog存在");
zkCli.delete("/itheima", -1);
System.out.println((zkCli.exists("/jackmablog", true)==null)?"/jackmablog不存在":"/jackmablog存在");
}
/**
* 持续注册监听器
* @throws InterruptedException
* @throws KeeperException
*/
@Test
public void listenerRedister() throws KeeperException, InterruptedException {
//在znode /java上注册监听器
//zkCli.create("/java", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zkCli.exists("/java", true);
Thread.sleep(Long.MAX_VALUE);
}
}
3、ZK持续注册监听器
package cn.itcast.zk.test;
import java.util.concurrent.CountDownLatch;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper.States;
/**
* 本类主要实现客户端持续向ZK注册监听器,保障监听器永久有效
* @author songjq
*
*/
public class ZkListenerRegister {
private static ZooKeeper zk1_;
public static void waitUntilConnected(ZooKeeper zooKeeper, CountDownLatch connectedLatch) {
if (States.CONNECTING == zooKeeper.getState()) {
try {
connectedLatch.await();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
static class ConnectedWatcher implements Watcher {
private CountDownLatch connectedLatch;
ConnectedWatcher(CountDownLatch connectedLatch) {
this.connectedLatch = connectedLatch;
}
/**
* 监听器回调方法
* 如果需要对某个znode进行持续监听,需要重新在回调方法中注册监听器
*/
@Override
public void process(WatchedEvent event) {
System.out.println("节点:" + event.getPath() + " 发生了事件:" + event.getType());
if (event.getState() == KeeperState.SyncConnected) {
connectedLatch.countDown();
}
/**
* 例如在exists上注册监听器
* 备注:exists上注册的监听器只能对注册的znode进行监听,不能监听子znode
* 若要监听子znode可以在getChildren上注册监听
*/
try {
zk1_.exists("/sjq", true);
zk1_.getChildren("/sjq", true);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
}
public ZooKeeper getConnection(String hostports, int times) {
ZooKeeper zktmp = null;
try {
CountDownLatch connectedLatch = new CountDownLatch(1);
Watcher watcher = new ConnectedWatcher(connectedLatch);
zktmp = new ZooKeeper(hostports, times, watcher);
waitUntilConnected(zktmp, connectedLatch);
} catch (Exception e) {
System.out.println(e);
return null;
}
return zktmp;
}
static private ZkListenerRegister static_;
static public ZkListenerRegister Instance() {
if (static_ == null) {
static_ = new ZkListenerRegister();
}
return static_;
}
public static void main(String[] args) throws Exception {
String hostports = "192.168.1.201:2181,192.168.1.202:2181,192.168.1.203:2181";
ZkListenerRegister instance = ZkListenerRegister.Instance();
zk1_ = instance.getConnection(hostports, 2000);
zk1_.create("/sjq", "123".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk1_.exists("/sjq", true);
Thread.sleep(Long.MAX_VALUE);
}
}