一、Zookeeper原生客户端
1、jdk包引入
<?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>enjoy</groupId> <artifactId>zookeeperJavaApi</artifactId> <version>1.0-SNAPSHOT</version>
<dependencies> <dependency>
<groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version>
</dependency> <dependency>
<groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version>
</dependency> <dependency>
<groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version>
</dependency>
<dependency> <groupId>org.apache.curator</groupId> <artifactId>curator-framework</artifactId> <version>4.0.0</version>
</dependency> <dependency>
<groupId>org.apache.curator</groupId> <artifactId>curator-recipes</artifactId> <version>4.0.0</version>
</dependency> </dependencies>
<build> <plugins>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration>
<source>1.8</source>
<target>1.8</target> </configuration>
</plugin> </plugins>
</build> </project>
2、创建会话
package cn.enjoy.javaapi;
import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.junit.Test;
import java.util.concurrent.CountDownLatch;
public class TestCreateSession {
private static final String SERVER = "192.168.30.10:2181";
private final int SESSION_TIMEOUT = 30000;
@Test
public void testSession1() throws Exception {
ZooKeeper zooKeeper = new ZooKeeper(SERVER,SESSION_TIMEOUT,null);
System.out.println(zooKeeper);
System.out.println(zooKeeper.getState());
}
private CountDownLatch countDownLatch = new CountDownLatch(1);
@Test
public void testSession2() throws Exception {
ZooKeeper zooKeeper = new ZooKeeper(SERVER, SESSION_TIMEOUT, new Watcher()
{ @Override
public void process(WatchedEvent watchedEvent)
{ if(watchedEvent.getState() == Event.KeeperState.SyncConnected) {
countDownLatch.countDown();
System.out.println("已经获得了连接");
} }
});
countDownLatch.await(); System.out.println(zooKeeper.getState());
}
}
3、基本操作
package com.guazi.scmp.settle.service.impl;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
public class TestJavaApi implements Watcher {
private static final int SESSION_TIMEOUT = 10000;
private static final String CONNECTION_STRING = "127.0.0.1:2181";
private static final String ZK_PATH = "/leader";
private ZooKeeper zk = null;
private CountDownLatch connectedSemaphore = new CountDownLatch(1);
public void createConnection(String connectString, int sessionTimeout) {
this.releaseConnection();
try {
zk = new ZooKeeper(connectString, sessionTimeout, this);
connectedSemaphore.await();
} catch (InterruptedException e) {
System.out.println("连接创建失败,发生 InterruptedException");
e.printStackTrace();
} catch (IOException e) {
System.out.println("连接创建失败,发生 IOException");
e.printStackTrace();
}
}
public void releaseConnection() {
if (null != this.zk) {
try {
this.zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean createPath(String path, String data) {
try {
System.out.println("节点创建成功, Path: "
+ this.zk.create(path,
data.getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL)
+ ", content: " + data);
} catch (KeeperException e) {
System.out.println("节点创建失败,发生KeeperException");
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("节点创建失败,发生 InterruptedException");
e.printStackTrace();
}
return true;
}
public String readData(String path) {
try {
System.out.println("获取数据成功,path:" + path);
return new String(this.zk.getData(path, false, null));
} catch (KeeperException e) {
System.out.println("读取数据失败,发生KeeperException,path: " + path);
e.printStackTrace();
return "";
} catch (InterruptedException e) {
System.out.println("读取数据失败,发生 InterruptedException,path: " + path);
e.printStackTrace();
return "";
}
}
public boolean writeData(String path, String data) {
try {
System.out.println("更新数据成功,path:" + path + ", stat: " +
this.zk.setData(path, data.getBytes(), -1));
} catch (KeeperException e) {
System.out.println("更新数据失败,发生KeeperException,path: " + path);
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("更新数据失败,发生 InterruptedException,path: " + path);
e.printStackTrace();
}
return false;
}
public void deleteNode(String path) {
try {
this.zk.delete(path, -1);
System.out.println("删除节点成功,path:" + path);
} catch (KeeperException e) {
System.out.println("删除节点失败,发生KeeperException,path: " + path);
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("删除节点失败,发生 InterruptedException,path: " + path);
e.printStackTrace();
}
}
public static void main(String[] args) {
TestJavaApi sample = new TestJavaApi();
sample.createConnection(CONNECTION_STRING, SESSION_TIMEOUT);
if (sample.createPath(ZK_PATH, "我是节点初始内容")) {
System.out.println();
System.out.println("数据内容: " + sample.readData(ZK_PATH) + "\n");
sample.writeData(ZK_PATH, "更新后的数据");
System.out.println("数据内容: " + sample.readData(ZK_PATH) + "\n");
sample.deleteNode(ZK_PATH);
}
sample.releaseConnection();
}
@Override
public void process(WatchedEvent event) {
System.out.println("收到事件通知:" + event.getState() + "\n");
if (Event.KeeperState.SyncConnected == event.getState()) {
connectedSemaphore.countDown();
}
}
}
4、watch机制
package com.guazi.scmp.settle.service.impl;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class ZooKeeperWatcher implements Watcher {
AtomicInteger seq = new AtomicInteger();
private static final int SESSION_TIMEOUT = 10000;
private static final String CONNECTION_ADDR = "127.0.0.1:2181";
private static final String PARENT_PATH = "/testWatch";
private static final String CHILDREN_PATH = "/testWatch/children";
private static final String LOG_PREFIX_OF_MAIN = "【Main】";
private ZooKeeper zk = null;
private CountDownLatch connectedSemaphore = new CountDownLatch(1);
public void createConnection(String connectAddr, int sessionTimeout) {
this.releaseConnection();
try {
zk = new ZooKeeper(connectAddr, sessionTimeout, this);
System.out.println(LOG_PREFIX_OF_MAIN + "开始连接ZK服务器");
connectedSemaphore.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public void releaseConnection() {
if (this.zk != null) {
try {
this.zk.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public boolean createPath(String path, String data) {
try {
this.zk.exists(path, true);
System.out.println(LOG_PREFIX_OF_MAIN + "节点创建成功, Path: " +
this.zk.create(
path,
data.getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT ) +
", content: " + data);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public String readData(String path, boolean needWatch) {
try {
return new String(this.zk.getData(path, needWatch, null));
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
public boolean writeData(String path, String data) {
try {
System.out.println(LOG_PREFIX_OF_MAIN + "更新数据成功,path:" + path + ", stat: " +
this.zk.setData(path, data.getBytes(), -1));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public void deleteNode(String path) {
try {
this.zk.delete(path, -1);
System.out.println(LOG_PREFIX_OF_MAIN + "删除节点成功,path:" + path);
} catch (Exception e) {
e.printStackTrace();
}
}
public Stat exists(String path, boolean needWatch) {
try {
return this.zk.exists(path, needWatch);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private List<String> getChildren(String path, boolean needWatch) {
try {
return this.zk.getChildren(path, needWatch);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public void deleteAllTestPath() {
if(this.exists(CHILDREN_PATH, false) != null){
this.deleteNode(CHILDREN_PATH);
}
if(this.exists(PARENT_PATH, false) != null){
this.deleteNode(PARENT_PATH);
}
}
@Override
public void process(WatchedEvent event) {
System.out.println("进入 process 。。。。。event = " + event);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (event == null) {
return;
}
Event.KeeperState keeperState = event.getState();
Event.EventType eventType = event.getType();
String path = event.getPath();
String logPrefix = "【Watcher-" + this.seq.incrementAndGet() + "】";
System.out.println(logPrefix + "收到Watcher通知");
System.out.println(logPrefix + "连接状态:\t" + keeperState.toString());
System.out.println(logPrefix + "事件类型:\t" + eventType.toString());
if (Event.KeeperState.SyncConnected == keeperState) {
if (Event.EventType.None == eventType) {
System.out.println(logPrefix + "成功连接上ZK服务器");
connectedSemaphore.countDown();
}
if (Event.EventType.NodeCreated == eventType) {
System.out.println(logPrefix + "节点创建");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.exists(path, true);
}
else if (Event.EventType.NodeDataChanged == eventType) {
System.out.println(logPrefix + "节点数据更新");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(logPrefix + "数据内容: " + this.readData(PARENT_PATH, true));
}
else if (Event.EventType.NodeChildrenChanged == eventType) {
System.out.println(logPrefix + "子节点变更");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(logPrefix + "子节点列表:" + this.getChildren(PARENT_PATH, true));
}
else if (Event.EventType.NodeDeleted == eventType) {
System.out.println(logPrefix + "节点 " + path + " 被删除");
}
}
else if (Event.KeeperState.Disconnected == keeperState) {
System.out.println(logPrefix + "与ZK服务器断开连接");
}
else if (Event.KeeperState.AuthFailed == keeperState) {
System.out.println(logPrefix + "权限检查失败");
}
else if (Event.KeeperState.Expired == keeperState) {
System.out.println(logPrefix + "会话失效");
}
System.out.println("--------------------------------------------");
}
public static void main(String[] args) throws Exception {
ZooKeeperWatcher zkWatch = new ZooKeeperWatcher();
zkWatch.createConnection(CONNECTION_ADDR, SESSION_TIMEOUT);
Thread.sleep(1000);
zkWatch.deleteAllTestPath();
if (zkWatch.createPath(PARENT_PATH, System.currentTimeMillis() + "")) {
System.out.println("---------------------- read parent ----------------------------");
zkWatch.writeData(PARENT_PATH, System.currentTimeMillis() + "");
System.out.println("---------------------- read children path ----------------------------");
zkWatch.getChildren(PARENT_PATH, true);
Thread.sleep(1000);
zkWatch.createPath(CHILDREN_PATH, System.currentTimeMillis() + "");
Thread.sleep(1000);
zkWatch.readData(CHILDREN_PATH, true);
zkWatch.writeData(CHILDREN_PATH, System.currentTimeMillis() + "");
}
Thread.sleep(20000);
zkWatch.deleteAllTestPath();
Thread.sleep(1000);
zkWatch.releaseConnection();
}
}
5、ZK认证机制
package com.guazi.scmp.settle.service.impl;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class TestZookeeperAuth implements Watcher {
final static String CONNECT_ADDR = "127.0.0.1:2181";
final static String PATH = "/testAuth";
final static String PATH_DEL = "/testAuth/delNode";
final static String authentication_type = "digest";
final static String correctAuthentication = "123456";
final static String badAuthentication = "654321";
static ZooKeeper zk = null;
AtomicInteger seq = new AtomicInteger();
private static final String LOG_PREFIX_OF_MAIN = "【Main】";
private CountDownLatch connectedSemaphore = new CountDownLatch(1);
@Override
public void process(WatchedEvent event) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (event==null) {
return;
}
Event.KeeperState keeperState = event.getState();
Event.EventType eventType = event.getType();
String path = event.getPath();
String logPrefix = "【Watcher-" + this.seq.incrementAndGet() + "】";
System.out.println(logPrefix + "收到Watcher通知");
System.out.println(logPrefix + "连接状态:\t" + keeperState.toString());
System.out.println(logPrefix + "事件类型:\t" + eventType.toString());
if (Event.KeeperState.SyncConnected == keeperState) {
if (Event.EventType.None == eventType) {
System.out.println(logPrefix + "成功连接上ZK服务器");
connectedSemaphore.countDown();
}
} else if (Event.KeeperState.Disconnected == keeperState) {
System.out.println(logPrefix + "与ZK服务器断开连接");
} else if (Event.KeeperState.AuthFailed == keeperState) {
System.out.println(logPrefix + "权限检查失败");
} else if (Event.KeeperState.Expired == keeperState) {
System.out.println(logPrefix + "会话失效");
}
System.out.println("--------------------------------------------");
}
public void createConnection(String connectString, int sessionTimeout) {
this.releaseConnection();
try {
zk = new ZooKeeper(connectString, sessionTimeout, this);
zk.addAuthInfo(authentication_type,correctAuthentication.getBytes());
System.out.println(LOG_PREFIX_OF_MAIN + "开始连接ZK服务器");
connectedSemaphore.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public void releaseConnection() {
if (this.zk!=null) {
try {
this.zk.close();
} catch (InterruptedException e) {
}
}
}
public static void main(String[] args) throws Exception {
TestZookeeperAuth testAuth = new TestZookeeperAuth();
testAuth.createConnection(CONNECT_ADDR,2000);
List<ACL> acls = new ArrayList<ACL>(1);
for (ACL ids_acl : ZooDefs.Ids.CREATOR_ALL_ACL) {
acls.add(ids_acl);
}
try {
zk.create(PATH, "init content".getBytes(), acls, CreateMode.PERSISTENT);
System.out.println("使用授权key:" + correctAuthentication + "创建节点:"+ PATH + ", 初始内容是: init content");
} catch (Exception e) {
e.printStackTrace();
}
try {
zk.create(PATH_DEL, "will be deleted! ".getBytes(), acls, CreateMode.PERSISTENT);
System.out.println("使用授权key:" + correctAuthentication + "创建节点:"+ PATH_DEL + ", 初始内容是: init content");
} catch (Exception e) {
e.printStackTrace();
}
getDataByNoAuthentication();
getDataByBadAuthentication();
getDataByCorrectAuthentication();
updateDataByNoAuthentication();
updateDataByBadAuthentication();
updateDataByCorrectAuthentication();
deleteNodeByBadAuthentication();
deleteNodeByNoAuthentication();
deleteNodeByCorrectAuthentication();
Thread.sleep(1000);
deleteParent();
testAuth.releaseConnection();
}
static void getDataByBadAuthentication() {
String prefix = "[使用错误的授权信息]";
try {
ZooKeeper badzk = new ZooKeeper(CONNECT_ADDR, 2000, null);
badzk.addAuthInfo(authentication_type,badAuthentication.getBytes());
Thread.sleep(2000);
System.out.println(prefix + "获取数据:" + PATH);
System.out.println(prefix + "成功获取数据:" + badzk.getData(PATH, false, null));
} catch (Exception e) {
System.err.println(prefix + "获取数据失败,原因:" + e.getMessage());
}
}
static void getDataByNoAuthentication() {
String prefix = "[不使用任何授权信息]";
try {
System.out.println(prefix + "获取数据:" + PATH);
ZooKeeper nozk = new ZooKeeper(CONNECT_ADDR, 2000, null);
Thread.sleep(2000);
System.out.println(prefix + "成功获取数据:" + nozk.getData(PATH, false, null));
} catch (Exception e) {
System.err.println(prefix + "获取数据失败,原因:" + e.getMessage());
}
}
static void getDataByCorrectAuthentication() {
String prefix = "[使用正确的授权信息]";
try {
System.out.println(prefix + "获取数据:" + PATH);
System.out.println(prefix + "成功获取数据:" + zk.getData(PATH, false, null));
} catch (Exception e) {
System.out.println(prefix + "获取数据失败,原因:" + e.getMessage());
}
}
static void updateDataByNoAuthentication() {
String prefix = "[不使用任何授权信息]";
System.out.println(prefix + "更新数据: " + PATH);
try {
ZooKeeper nozk = new ZooKeeper(CONNECT_ADDR, 2000, null);
Thread.sleep(2000);
Stat stat = nozk.exists(PATH, false);
if (stat!=null) {
nozk.setData(PATH, prefix.getBytes(), -1);
System.out.println(prefix + "更新成功");
}
} catch (Exception e) {
System.err.println(prefix + "更新失败,原因是:" + e.getMessage());
}
}
static void updateDataByBadAuthentication() {
String prefix = "[使用错误的授权信息]";
System.out.println(prefix + "更新数据:" + PATH);
try {
ZooKeeper badzk = new ZooKeeper(CONNECT_ADDR, 2000, null);
badzk.addAuthInfo(authentication_type,badAuthentication.getBytes());
Thread.sleep(2000);
Stat stat = badzk.exists(PATH, false);
if (stat!=null) {
badzk.setData(PATH, prefix.getBytes(), -1);
System.out.println(prefix + "更新成功");
}
} catch (Exception e) {
System.err.println(prefix + "更新失败,原因是:" + e.getMessage());
}
}
static void updateDataByCorrectAuthentication() {
String prefix = "[使用正确的授权信息]";
System.out.println(prefix + "更新数据:" + PATH);
try {
Stat stat = zk.exists(PATH, false);
if (stat!=null) {
zk.setData(PATH, prefix.getBytes(), -1);
System.out.println(prefix + "更新成功");
}
} catch (Exception e) {
System.err.println(prefix + "更新失败,原因是:" + e.getMessage());
}
}
static void deleteNodeByNoAuthentication() throws Exception {
String prefix = "[不使用任何授权信息]";
try {
System.out.println(prefix + "删除节点:" + PATH_DEL);
ZooKeeper nozk = new ZooKeeper(CONNECT_ADDR, 2000, null);
Thread.sleep(2000);
Stat stat = nozk.exists(PATH_DEL, false);
if (stat!=null) {
nozk.delete(PATH_DEL,-1);
System.out.println(prefix + "删除成功");
}
} catch (Exception e) {
System.err.println(prefix + "删除失败,原因是:" + e.getMessage());
}
}
static void deleteNodeByBadAuthentication() throws Exception {
String prefix = "[使用错误的授权信息]";
try {
System.out.println(prefix + "删除节点:" + PATH_DEL);
ZooKeeper badzk = new ZooKeeper(CONNECT_ADDR, 2000, null);
badzk.addAuthInfo(authentication_type,badAuthentication.getBytes());
Thread.sleep(2000);
Stat stat = badzk.exists(PATH_DEL, false);
if (stat!=null) {
badzk.delete(PATH_DEL, -1);
System.out.println(prefix + "删除成功");
}
} catch (Exception e) {
System.err.println(prefix + "删除失败,原因是:" + e.getMessage());
}
}
static void deleteNodeByCorrectAuthentication() throws Exception {
String prefix = "[使用正确的授权信息]";
try {
System.out.println(prefix + "删除节点:" + PATH_DEL);
Stat stat = zk.exists(PATH_DEL, false);
if (stat!=null) {
zk.delete(PATH_DEL, -1);
System.out.println(prefix + "删除成功");
}
} catch (Exception e) {
System.out.println(prefix + "删除失败,原因是:" + e.getMessage());
}
}
static void deleteParent() throws Exception {
try {
Stat stat = zk.exists(PATH_DEL, false);
if (stat == null) {
zk.delete(PATH, -1);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
二、zkclient
1、基本操作
package cn.enjoy.zkclient;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import java.util.List;
public class ZkClientOperator {
static final String CONNECT_ADDR = "127.0.0.1:2181";
static final int SESSION_OUTTIME = 10000;
public static void main(String[] args) throws Exception {
ZkClient zkc = new ZkClient(CONNECT_ADDR, SESSION_OUTTIME);
zkc.createEphemeral("/temp");
zkc.createPersistent("/super/c1", true);
Thread.sleep(10000);
zkc.delete("/temp");
zkc.deleteRecursive("/super");
zkc.createPersistent("/super", "1234");
zkc.createPersistent("/super/c1", "c1内容");
zkc.createPersistent("/super/c2", "c2内容");
List<String> list = zkc.getChildren("/super");
for(String p : list){
System.out.println(p);
String rp = "/super/" + p;
String data = zkc.readData(rp);
System.out.println("节点为:" + rp + ",内容为: " + data);
}
zkc.writeData("/super/c1", "新内容");
System.out.println(zkc.readData("/super/c1").toString());
System.out.println(zkc.exists("/super/c1"));
zkc.deleteRecursive("/super");
}
}
2、watch
package cn.enjoy.zkclient;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
import org.junit.Test;
import java.util.List;
public class TestZkClientWatcher {
static final String CONNECT_ADDR = "127.0.0.1:2181";
static final int SESSION_OUTTIME = 10000;
@Test
public void testZkClientWatcher1() throws Exception {
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
zkc.subscribeChildChanges("/super", new IZkChildListener() {
@Override
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
System.out.println("parentPath: " + parentPath);
System.out.println("currentChilds: " + currentChilds);
}
});
Thread.sleep(3000);
zkc.createPersistent("/super");
Thread.sleep(1000);
zkc.createPersistent("/super" + "/" + "c1", "c1内容");
Thread.sleep(1000);
zkc.createPersistent("/super" + "/" + "c2", "c2内容");
Thread.sleep(1000);
zkc.delete("/super/c2");
Thread.sleep(1000);
zkc.deleteRecursive("/super");
Thread.sleep(Integer.MAX_VALUE);
}
@Test
public void testZkClientWatcher2() throws Exception {
ZkClient zkc = new ZkClient(new ZkConnection(CONNECT_ADDR), SESSION_OUTTIME);
zkc.createPersistent("/super", "1234");
zkc.subscribeDataChanges("/super", new IZkDataListener() {
@Override
public void handleDataDeleted(String path) throws Exception {
System.out.println("删除的节点为:" + path);
}
@Override
public void handleDataChange(String path, Object data) throws Exception {
System.out.println("变更的节点为:" + path + ", 变更内容为:" + data);
}
});
Thread.sleep(3000);
zkc.writeData("/super", "456", -1);
Thread.sleep(1000);
zkc.delete("/super");
Thread.sleep(Integer.MAX_VALUE);
}
}