0. 前言

zookeeper安装及使用  http://www.cnblogs.com/rocky-fang/p/7880309.html

1. 开发环境配置

1.1 idea创建一个maven工程

1.2 pom配置jar

<?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.rocky.learn</groupId>
<artifactId>zk</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency> <!-- https://mvnrepository.com/artifact/org.apache.zookeeper/zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency> </dependencies> </project>

2. API使用

2.1 连接Zookeep Server

code

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/12.
*/
public class ZookeeperTestConnection implements Watcher {
private static CountDownLatch countDownLatch = new CountDownLatch(1); public void process(WatchedEvent event) {
System.out.println("receive the event:"+event);
if(Event.KeeperState.SyncConnected == event.getState())
countDownLatch.countDown();
}
public static final String ADDRESS = "192.168.1.8:2181"; public static void main(String[] args) throws IOException {
ZooKeeper zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestConnection());
System.out.println(zooKeeper.getState());
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("zookeeper session established");
}
}

控制台

2.2 创建节点

2.2.1 同步创建

code

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/12.
*/
public class ZookeeperTestCreateNodeSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX = "/mytest-sync-create-";
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestCreateNodeSync());
System.out.println("state:"+zooKeeper.getState());
countDownLatch.await();
String path1 = zooKeeper.create(PREFIX, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("success create znode:"+ path1);
String path2 = zooKeeper.create(PREFIX, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
System.out.println("success create znode:"+ path2);
zooKeeper.close();
} public void process(WatchedEvent event) {
//连上了
if(Event.KeeperState.SyncConnected == event.getState())
countDownLatch.countDown();
}
}

控制台

2.2.2 异步创建

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/12.
*/
public class ZookeeperTestCreateNodeAsync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX_ASYNC = "/mytest-async-create-";
public static void main(String[] args) throws IOException, InterruptedException {
ZooKeeper zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestCreateNodeAsync());
System.out.println("state:"+zooKeeper.getState());
countDownLatch.await();
zooKeeper.create(PREFIX_ASYNC, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
new IStringCallBack(), "my test text...1");
zooKeeper.create(PREFIX_ASYNC, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
new IStringCallBack(), "my test text...2");
zooKeeper.create(PREFIX_ASYNC, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,
new IStringCallBack(), "my test text...3");
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState())
countDownLatch.countDown();
} }
class IStringCallBack implements AsyncCallback.StringCallback {
public void processResult(int rc, String path, Object ctx, String name) {
System.out.println("rc:"+rc+",path:"+path+",ctx:"+ctx+"name,"+name);
}
}

控制台

说明:同步需要关注接口异常,异步接口不会反回异常,而是在回调函数中通过result code体现

2.3 创建节点

只允许删除叶子节点,即如果节点包含子节点,则必须先删除子节点才能删除本节点。

2.3.1 同步方式

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/12.
*/
public class ZookeeperTestDeleteNodeSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX_SYNC = "/mytest-sync-delete-"; public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestDeleteNodeSync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "mydelete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create(PREFIX_SYNC + "/c1", "mydelete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
try {
zooKeeper.delete(PREFIX_SYNC, -1);
} catch (Exception e) {
System.out.println("faile to delete path:"+PREFIX_SYNC);
}
zooKeeper.delete(PREFIX_SYNC + "/c1", -1);
System.out.println("success to delete /c1");
zooKeeper.delete(PREFIX_SYNC , -1);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath())
countDownLatch.countDown();
}
}
}

控制台

2.3.2 异步方式

import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/12.
*/
public class ZookeeperTestDeleteNodeASync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX_SYNC = "/mytest-async-delete-"; public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
ZooKeeper zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestDeleteNodeASync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "mydelete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create(PREFIX_SYNC + "/c1", "mydelete".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); zooKeeper.delete(PREFIX_SYNC , -1, new IVoidCallback(), null);
zooKeeper.delete(PREFIX_SYNC + "/c1", -1, new IVoidCallback(), null);
zooKeeper.delete(PREFIX_SYNC , -1, new IVoidCallback(), null); System.out.println("success to delete /c1");
zooKeeper.delete(PREFIX_SYNC , -1);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath())
countDownLatch.countDown();
}
} }
class IVoidCallback implements AsyncCallback.VoidCallback {
public void processResult(int rc, String path, Object ctx) {
System.out.println(rc + "::" + path + "::" +ctx);
}
}

控制台

2.4 获取子节点

2.4.1 同步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Id; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestGetChildrenNodeSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX_SYNC = "/mytest-sync-getChild-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestGetChildrenNodeSync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create(PREFIX_SYNC + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(zooKeeper.getChildren(PREFIX_SYNC, true));
zooKeeper.create(PREFIX_SYNC + "/c2", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(zooKeeper.getChildren(PREFIX_SYNC, true));
Thread.sleep(1000);
zooKeeper.create(PREFIX_SYNC + "/c3", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println(zooKeeper.getChildren(PREFIX_SYNC, true));
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeChildrenChanged == event.getType()){
try {
System.out.println("get Child:" + zooKeeper.getChildren(event.getPath(), true));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

控制台

Watcher通知是一次性的,即一旦触发一次通知后,该Watcher就失效了,因此客户端需要反复注册Watcher,即程序中在process里面又注册了Watcher,zooKeeper.getData(path,watch,stat), 第二个参数值设为true则添加一次监听, 否则,将无法获取c3节点的创建而导致子节点变化的事件。

2.4.2 异步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.List;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestGetChildrenNodeASync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "192.168.1.8:2181";
private static final String PREFIX_SYNC = "/mytest-async-getChild-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestGetChildrenNodeASync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.create(PREFIX_SYNC + "/c1", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.getChildren(PREFIX_SYNC, true, new IChildren2Callback(), null);
zooKeeper.create(PREFIX_SYNC + "/c2", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.getChildren(PREFIX_SYNC, true, new IChildren2Callback(), null);
Thread.sleep(1000);
zooKeeper.create(PREFIX_SYNC + "/c3", "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.getChildren(PREFIX_SYNC, true, new IChildren2Callback(), null);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeChildrenChanged == event.getType()){
try {
System.out.println("get Child:" + zooKeeper.getChildren(event.getPath(), true));
} catch (Exception e) {
e.printStackTrace();
}
}
}
} }
class IChildren2Callback implements AsyncCallback.Children2Callback {
public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
System.out.println(rc + "::" + path + "::" +ctx +"::" + children + "::" + stat);
} }

控制台

2.5 节点的数据获取

2.5.1 同步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestGetNodeDataSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-sync-getData4-";
private static ZooKeeper zooKeeper ;
private static final Stat stat = new Stat();
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestGetNodeDataSync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "hellodata".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("the data of node:" + new String(zooKeeper.getData(PREFIX_SYNC, true, stat)));
System.out.println("czxid::"+stat.getCzxid()+",mzxid::" + stat.getMzxid() + ",version::" + stat.getVersion());
zooKeeper.setData(PREFIX_SYNC, "hello2data".getBytes(), -1);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == event.getType()){
try {
System.out.println("the data of:" + event.getPath() + " is::" + new String(zooKeeper.getData(event.getPath(), true, stat)));
System.out.println("watch czxid::"+stat.getCzxid()+",mzxid::" + stat.getMzxid() + ",version::" + stat.getVersion());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

控制台

2.5.2 异步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestGetNodeDataASync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-async-getData8-";
private static ZooKeeper zooKeeper ;
private static final Stat stat = new Stat();
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestGetNodeDataASync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "hello7data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.getData(PREFIX_SYNC, true, new IDataCallback(), null);
for(int i=0; i<3; i++){
zooKeeper.setData(PREFIX_SYNC, "hello6data".getBytes(), -1);
}
Thread.sleep(Integer.MAX_VALUE);
}
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == event.getType()){
try {
zooKeeper.getData(PREFIX_SYNC, true, new IDataCallback(), null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} }
class IDataCallback implements AsyncCallback.DataCallback {
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
System.out.println("watch rc::" + rc + ", path::" + path + ", ctx::" + ctx +", data::" + new String(data));
System.out.println("watch czxid::"+stat.getCzxid()+",mzxid::" + stat.getMzxid() + ",version::" + stat.getVersion());
}
}

控制台

2.6 更新数据

在更新数据时,setData方法存在一个version参数,其用于指定节点的数据版本,表明本次更新操作是针对指定的数据版本进行的,但是,在getData方法中,并没有提供根据指定数据版本来获取数据的接口,那么,这里为何要指定数据更新版本呢,这里方便理解,可以等效于CAS(compare and swap),对于值V,每次更新之前都会比较其值是否是预期值A,只有符合预期,才会将V原子化地更新到新值B。Zookeeper的setData接口中的version参数可以对应预期值,表明是针对哪个数据版本进行更新,假如一个客户端试图进行更新操作,它会携带上次获取到的version值进行更新,而如果这段时间内,Zookeeper服务器上该节点的数据已经被其他客户端更新,那么其数据版本也会相应更新,而客户端携带的version将无法匹配,无法更新成功,因此可以有效地避免分布式更新的并发问题

2.6.1 同步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestSetNodeDataSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-sync-setData2-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestSetNodeDataSync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "hello6data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("the data of node:" + new String(zooKeeper.getData(PREFIX_SYNC, true, null)));
Stat stat = zooKeeper.setData(PREFIX_SYNC, "hello6data".getBytes(), -1);
System.out.println("czxid::"+stat.getCzxid()+",mzxid::" + stat.getMzxid() + ",version::" + stat.getVersion());
Stat stat2 = zooKeeper.setData(PREFIX_SYNC, "hello6data".getBytes(), stat.getVersion());
System.out.println("czxid::"+stat2.getCzxid()+",mzxid::" + stat2.getMzxid() + ",version::" + stat2.getVersion());
try {
zooKeeper.setData(PREFIX_SYNC, "hello6data".getBytes(), stat.getVersion());
} catch (Exception e) {
System.out.println("exception: " + e);
}
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == event.getType()){
try {
System.out.println("watch the data of:" + event.getPath() + " is::" + new String(zooKeeper.getData(event.getPath(), true, null)));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}

控制台

2.6.2  异步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestSetNodeDataASync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-async-setData4-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestSetNodeDataASync());
countDownLatch.await();
zooKeeper.create(PREFIX_SYNC, "hello".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.setData(PREFIX_SYNC, "hello2".getBytes(), -1, new StatCallback(), null);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}
}
} }
class StatCallback implements AsyncCallback.StatCallback {
public void processResult(int rc, String path, Object ctx, Stat stat) {
System.out.println("rc:"+rc + ", path:" + path + ",ctx:" + ctx + ", stat:" + stat);
}
}

控制台

rc(ResultCode)为0,表明成功更新节点数据。

2.7 检查节点是否存在

2.7.1 同步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestExistSync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-sync-exist-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestExistSync());
countDownLatch.await();
zooKeeper.exists(PREFIX_SYNC, true);
zooKeeper.create(PREFIX_SYNC, "hello6data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zooKeeper.setData(PREFIX_SYNC, "hello6data".getBytes(), -1);
zooKeeper.delete(PREFIX_SYNC, -1);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
try {
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == event.getType()){
System.out.println("node " + event.getPath() + " changed." );
zooKeeper.exists(event.getPath(), true);
}else if(Event.EventType.NodeCreated == event.getType()){
System.out.println("node " + event.getPath() + " created.");
zooKeeper.exists(event.getPath(), true);
}else if(Event.EventType.NodeDeleted == event.getType()){
System.out.println("node " + event.getPath() + " deleted.");
zooKeeper.exists(event.getPath(), true);
}
} catch (Exception e) {
e.printStackTrace();
} }
}
}

控制台

2.7.2 异步方式

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestExistASync implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-async-exist8-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestExistASync());
countDownLatch.await();
zooKeeper.exists(PREFIX_SYNC, true, new IStaCallback(), null);
zooKeeper.create(PREFIX_SYNC, "111".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.setData(PREFIX_SYNC, "222".getBytes(), -1);
//判断存在 并加监听
zooKeeper.exists(PREFIX_SYNC + "/c2", true, new IStaCallback(), null);
zooKeeper.create(PREFIX_SYNC + "/c2", "111".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zooKeeper.delete(PREFIX_SYNC + "/c2", -1);
// zooKeeper.exists(PREFIX_SYNC , true, new IStaCallback(), null);
//上面修改数据 那步 对PREFIX_SYNC添加了一个监听
zooKeeper.delete(PREFIX_SYNC, -1);
Thread.sleep(Integer.MAX_VALUE); }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
try {
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}else if(Event.EventType.NodeDataChanged == event.getType()){
System.out.println("node " + event.getPath() + " changed." );
zooKeeper.exists(event.getPath(), true, new IStaCallback(), null);
}else if(Event.EventType.NodeCreated == event.getType()){
System.out.println("node " + event.getPath() + " created.");
zooKeeper.exists(event.getPath(), true, new IStaCallback(), null);
}else if(Event.EventType.NodeDeleted == event.getType()){
System.out.println("node " + event.getPath() + " deleted.");
zooKeeper.exists(event.getPath(), true, new IStaCallback(), null);
}
} catch (Exception e) {
e.printStackTrace();
} }
} }
class IStaCallback implements AsyncCallback.StatCallback {
public void processResult(int rc, String path, Object ctx, Stat stat) {
System.out.println("rc:" + rc + ",path: " + path + ",ctx:" + ctx + ", stat:" + stat);
}
}

控制台

rc:-101,path: /mytest-async-exist8-,ctx:null, stat:null
node /mytest-async-exist8- created.
rc:0,path: /mytest-async-exist8-,ctx:null, stat:8590337352,8590337352,1526279675044,1526279675044,0,0,0,0,3,0,8590337352 node /mytest-async-exist8- changed.
rc:0,path: /mytest-async-exist8-,ctx:null, stat:8590337352,8590337353,1526279675044,1526279675095,1,0,0,0,3,0,8590337352 rc:-101,path: /mytest-async-exist8-/c2,ctx:null, stat:null
node /mytest-async-exist8-/c2 created.
rc:0,path: /mytest-async-exist8-/c2,ctx:null, stat:8590337354,8590337354,1526279675128,1526279675128,0,0,0,0,3,0,8590337354 node /mytest-async-exist8-/c2 deleted.
rc:-101,path: /mytest-async-exist8-/c2,ctx:null, stat:null
node /mytest-async-exist8- deleted.
rc:-101,path: /mytest-async-exist8-,ctx:null, stat:null

rc:-101 节点不存在去

2.8 权限相关

zookeeper使用ACL机制来实现权限控制, ACL机制主要分为3个方面,权限模式,权限ID和权限

2.8.1 权限模式

 1) IP

  ip模式是指权限针对这个ip而设置的,比如"ip:192.168.0.6",即允许这个ip访问数据节点

2) digest

digest模式是最常用的一种模式,形如"username:password"的方式。

 3) world

该模式对所有用户开放

4) super

超级管理员模式。需要在zkServer.sh中配置,形如"super:password" ,需要重启服务器

2.8.2 权限ID

根据不同模式 授权给的不同对象, ip模式为ip地址, digest模式为username

2.8.2 权限

即允许的操作 CRUD等

2.8.4 删除节点+权限

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat; import java.io.IOException;
import java.util.concurrent.CountDownLatch; /**
* @Author: rocky
* @Date: Created in 2018/5/13.
*/
public class ZookeeperTestAcl implements Watcher {
private static final CountDownLatch countDownLatch = new CountDownLatch(1);
private static final String ADDRESS = "10.0.40.10:2181";
private static final String PREFIX_SYNC = "/mytest-sync-acl-";
private static ZooKeeper zooKeeper ;
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
try {
zooKeeper = new ZooKeeper(ADDRESS, 5000, new ZookeeperTestAcl());
countDownLatch.await();
zooKeeper.addAuthInfo("digest", "true".getBytes());
zooKeeper.create(PREFIX_SYNC, "111".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
zooKeeper.create(PREFIX_SYNC+"/c2", "222".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL);
ZooKeeper zk2 = new ZooKeeper(ADDRESS, 5000, null);
try {
zk2.delete(PREFIX_SYNC+"/c2", -1);
} catch (Exception e) {
System.out.println("delete exception: " + e);
}
ZooKeeper zk3 = new ZooKeeper(ADDRESS, 5000, null);
zk3.addAuthInfo("digest", "true".getBytes());
zk3.delete(PREFIX_SYNC+"/c2", -1);
System.out.println("delete mytest-sync-acl-/c2 success");
ZooKeeper zk4 = new ZooKeeper(ADDRESS, 5000, null);
zk4.delete(PREFIX_SYNC, -1);
System.out.println("delete mytest-sync-acl- success");
Thread.sleep(Integer.MAX_VALUE);
} catch (Exception e) {
System.out.println("exception ::" +e);
} }
public void process(WatchedEvent event) {
if(Event.KeeperState.SyncConnected == event.getState()){
if(Event.EventType.None == event.getType() && null == event.getPath()){
countDownLatch.countDown();
}
}
}
}

控制台

说明:

可以看到,第一次我们使用无权限的zk2去删除,显然会报错,第二次我们使用带权限的zk3去操作,子节点被删除成功,但是当我们使用zk4去执行删除操作的时候并没有指定任何权限,依然能够删除其父节点,说明zk在进行删除操作的时候,其权限的作用范围是其子节点。也就是说,当我们对一个节点添加了权限之后我们依然可以随意删除该节点但是对于这个节点的子节点,就必须拥有相应的权限才能删除。而且zk原生api不支持递归删除,即在存在子节点的情况下,不允许删除其父节点。

Zookeeper JAVA API的使用的更多相关文章

  1. 9. 使用ZooKeeper Java API编程

    ZooKeeper是用Java开发的,3.4.6版本的Java API文档可以在http://zookeeper.apache.org/doc/r3.4.6/api/index.html上找到. Ti ...

  2. Zookeeper java api

     Zookeeper java api 主要有以下几个: 方法名称 描述 String create(final String path, byte data[], List acl, CreateM ...

  3. 14.ZooKeeper Java API 使用样例

    转自:http://www.aboutyun.com/thread-7332-1-1.html package com.taobao.taokeeper.research.sample; import ...

  4. zookeeper Java API 简单操作示例

    本文主要介绍如何在java IDE中如何应用使用客户端与zookeeper服务器通信. 首先搭建maven环境,并在pom文件中加入zookeeper引用包: <!-- https://mvnr ...

  5. zookeeper JAVA API 简单操作

    package org.admln.program.Zoo_Test; import java.io.IOException; import java.security.NoSuchAlgorithm ...

  6. Zookeeper Java API调用

    引入zookeeper-3.4.11.jar public class ZooKeeperTest implements Watcher{ //public final static String z ...

  7. zookeeper java api(使用java代码操作zookeeper)

    1 导入相关的pom依赖 <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId&g ...

  8. Zookeeper Curator API 使用

    0. 原生 ZOOKEEPER JAVA API  http://www.cnblogs.com/rocky-fang/p/9030438.html 1. 概述 Curator采用cache封装对事件 ...

  9. ZooKeeper Java例子(六)

    A Simple Watch Client 为了向你介绍ZooKeeper Java API,我们开发了一个非常简单的监视器客户端.ZooKeeper客户端监视一个ZooKeeper节点的改变并且通过 ...

随机推荐

  1. 逻辑卷磁盘管理和dd命令

      底层PV 中层VG 上层LV   PE(phsical extent):在逻辑层次上,VG把PV分成固定大小的块,这些块就叫PE,默认为4M ,创建LV的过程就是分多少个PE的过程. 自动分区的过 ...

  2. 手动启动 oracle 服务

      手动启动 Oracle 服务 为了学习,我们常常会在个人PC上安装 Oracle 数据库,这大大影响了计算机的运行速度,尤其是计算机开机速度,如果 Oracle 使用频率并不是非常高,我们可以禁止 ...

  3. Python全栈开发:list、元祖常用方法操作

    列表[] 索引与切片#例题#li = ['yijiajun',[1,3,5,7,9],'zhangliang','zhaoritian','sunwukong'] # #例子1 找出列表中索引为0的元 ...

  4. 图示NP, P, NP-Complete和NP-Hard问题

    P问题是一类可以通过确定性图灵机(以下简称图灵机)在多项式时间(Polynomial time)内解决的问题集合. NP问题是一类可以通过非确定性图灵机( Non-deterministic Turi ...

  5. 20190418 CentOS7实用技能综合:系统安装 + WinScp客户端连接 + 防火墙端口号iptables + Nginx编译安装 + MySQL编译安装 + Redis编译安装 + MongoDB编译安装 + ActiveMQ/RocketMQ/RabbitMQ编译安装 + ...各类常用生产环境软件的编译安装

    系统安装 + WinScp客户端连接 + 防火墙端口号iptables + Nginx编译安装 + MySQL编译安装 + Redis编译安装 + MongoDB编译安装 + ActiveMQ/Roc ...

  6. Java网络编程基础之TCP粘包拆包

    TCP是个"流"协议,所谓流,就是没有界限的一串数据.大家可以想象河里的流水,他们是连成一片的,其间并没有分界线.TCP底层并不了解上层业务数据的具体含义,他会根据TCP缓冲区的实 ...

  7. tp5 数据库相关操作笔记

    这里如何连接多个数据库? 1,在conif.php文件中添加一个数据库配置(把database.php文件内容复制一份过来),这里取名为db2 2,在控制器的方法中使用 mysql中的参数绑定 mys ...

  8. 【CSS3】background-origin和background-clip的区别

    background-clip 与 background-origin是css3中引入的两个跟元素背景相关的属性,它们有相同的可选值,即border.padding.content三种,而且这两个属性 ...

  9. 发布aar到jcenter

    准备工作 创建bintray账号; 在https://bintray.com/, 选择如下图中,方框内"Sign Up Here": 选择合适的方式,创建账号: 新建仓库: Add ...

  10. CNN-利用1*1进行降维和升维

    降维: 比如某次卷积之后的结果是W*H*6的特征,现在需要用1*1的卷积核将其降维成W*H*5,即6个通道变成5个通道: 通过一次卷积操作,W*H*6将变为W*H*1,这样的话,使用5个1*1的卷积核 ...