1. ZkClient API简介
zkclient是Github上一个开源的ZooKeeper客户端,在原生ZooKeeper API接口上进行包装,同时在内部实现了session超时重连,Watcher反复注册等功能
2. Maven工程方式导入ZkClient API
通过POM.xml方式,指定依赖的zookeepr包以及zkclient包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.newforce</groupId>
<artifactId>testzkclient</artifactId>
<version>1.0-SNAPSHOT</version> <dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.5</version>
</dependency>
</dependencies> </project>
3. ZkClient API使用
3.1 create session 创建和zookeeper集群间的连接
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer; /**
* ZkClient library usage
*/
public class CreateSession {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer());
System.out.println("Connection OK!"); }
}
核心代码分析:
1)和zookeeper原生API不同,通过zkclient API创建会话,需要提供session timout, connection timeout两个定时器
2)同时要提供1个序列化器实例,原因在于后续创建znode节点时,写入的数据(java对象)会自动通过序列化器来转换为byte[]
3)同理,读取出的byte[]的数据,也会自动通过序列化器直接转换为Java对象
3.2 创建znode节点
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.CreateMode;
public class CreateNode { public static void main(String args[]){ ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer());
User u = new User();
String actual_path = zc.create("/node_zkclient", u, CreateMode.PERSISTENT); //直接将实例u写入,自动通过序列化为byte[]
System.out.println("Create path is: " + actual_path);
} private class User{
private Integer id;
private String name; public Integer getId(){
return this.id;
}
public String getName(){
return this.name;
}
public String getInfo(){
return this.name + this.id;
}
}//User
}
3.3 修改节点数据
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.CreateMode; public class SetData {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer()); User u = new User();
u.setId(1);
u.setName("shayzhang"); String actual_path = zc.create("/node_zkclient", u, CreateMode.PERSISTENT); u.setId(2);
u.setName("zhangjin");
zc.writeData(actual_path, u); //直接写入实例,自动通过连接创建时创建的序列化实例,转换为byte[] }
}
3.4 获取节点数据
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat; public class GetData {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer());
User u = new User();
u.setId(1);
u.setName("shayzhang"); String actual_path = zc.create("/node_zkclient", u, CreateMode.PERSISTENT);
System.out.println("Create path is: " + actual_path); Stat stat = new Stat();
u = zc.readData(actual_path, stat); if (u == null){
System.out.println("Node doesn't exist!");
}else{
System.out.println(u.getInfo());
System.out.println(stat);
}
}
}
3.5 获取子节点列表
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.List; public class GetChildren {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer()); User u = new User();
u.setId(1);
u.setName("shayzhang"); String actual_path = zc.create("/node_zkclient", u, CreateMode.PERSISTENT);
System.out.println("Create path is: " + actual_path);
List<String> children_list = zc.getChildren(actual_path);
System.out.println("Children list of /node_zkclient is : " + children_list.toString()); //打印子节点列表 }
}
3.6 删除节点
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer; public class DeleteNode {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer()); String delete_node = "/node_zkclient"; //delete node without children
boolean e1 = zc.delete(delete_node);
System.out.println("Delete node without children: " + e1); // delete node and all children
boolean e2 = zc.deleteRecursive(delete_node);
System.out.println("Delete node and children: " + e2); }
}
3.7 判断节点是否存在
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer; public class NodeExist {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer());
String check_node = "/node_zkclient";
boolean exist = zc.exists(check_node);
System.out.println("Node exist status is: " + exist); }
}
3.8 订阅子节点列表发生变化
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import java.util.List; public class SubscribeChildren {
public static void main(String args[]){
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new SerializableSerializer());
System.out.println("Connected to zk server!"); // subscribe children change event, multiple subscribe
List<String> results = zc.subscribeChildChanges("/node_zkclient", new ZkChildListener()); // sleep until receive event notify
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
} }//main private static class ZkChildListener implements IZkChildListener{
public void handleChildChange(String s, List<String> list) throws Exception {
//print parent path
System.out.println("Parent path: " + s);
//print current children
System.out.println("Current children: " + list.toString());
}
}//ZkChildListener
}
3.9 订阅数据变化
/**
* ZkClient library usage
*/
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer; public class SubscribeData {
public static void main(String args[]){
//使用了新的序列化器, zk命令行写入的数据才能被检测
ZkClient zc = new ZkClient("192.168.179.101:2181", 5000, 5000, new BytesPushThroughSerializer()); //写入什么直接当做byte[]进行存储
System.out.println("Connected to zk server!"); // subscribe data change event, multiple subscribe
zc.subscribeDataChanges("/node_zkclient", new ZkDataListener()); // sleep until receive event notify
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
} } private static class ZkDataListener implements IZkDataListener{
public void handleDataChange(String s, Object o) throws Exception { //覆写方法1
System.out.println("Path Data Changed: " + s);
System.out.println("Current Data: " + o.toString());
}
public void handleDataDeleted(String s) throws Exception { //覆写方法2
System.out.println("Data Deleted: " + s);
}
}//ZkDataListener
}