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. 工具IDEA 配置springboot+maven项目

    工具IDEA 配置springboot+maven项目 首先安装IDEA,至于怎么安装就不介绍了.. 第一步 配置maven环境 首先安装maven,先在网上下载一个maven包.在IDEA的sett ...

  2. Android-获取手机已经安装的程序

    有时候我们会查询手机里面是否安装了某个程序,或者获取已经安装软件名称的集合. android这边提供了相应的接口. [java] view plaincopy final PackageManager ...

  3. @ModelAttribute注解和POJO传参过程

    1.@ModelAttribute注解 @ModelAttribute主要有三个用途,对方法进行注解,对参数进行注解,还有@ModelAttribute和@RequestMapping一起对方法进行注 ...

  4. 【NOI2018】

    总之国赛已经过了1个月了. 感谢北大当初给我的一本约救我狗命,不然国赛就要没学上了. 铜牌倒数十多名,我觉得我也是混到了一种境界. 虽然对于集训队已经失去梦想,但是,Day1全场堪称最低的21分,也是 ...

  5. python学习,day3:函数式编程,递归和高阶函数

    # coding=utf-8 # Author: RyAn Bi def calc(n): #递归 print(n) if int(n/2) > 0: #设置条件,否则会循环999 次,报错, ...

  6. [BZOJ 5323][Jxoi2018]游戏

    传送门 \(\color{green}{solution}\) 它每次感染的人是它的倍数,那么我们只需要找出那些除了自己以外在\(l\), \(r\)内没有别的数是 它的约数的数,在这里称其为关键数. ...

  7. 虚拟机下设置CentOS 7使用固定IP地址

    1.设置虚拟机使用桥接网络 2.查看安装虚拟机软件的电脑IP信息 3.启动CentOS 7进行设置

  8. dubbo SPI设计

    SPI 全称为 Service Provider Interface,是一种服务发现机制.SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类.这样可以在运行时, ...

  9. MySQL 重命名数据库

    首先创建目标库 create database trgdb; 获取所有源库的表名 use information_schema; select table_name from TABLES where ...

  10. ClouderManager集群在Linux里浏览器默认是英文,在Win里浏览器是中文,怎么更改?(图文详解)

    不多说,直接上干货! 问题详情 在这里面如何英文改中文的吗? 莫非要把linux的语言环境给改了?? 我找找网页的语言字体怎么更改下 找到对应页面,修改成中文 解决办法 刷新下,即可 欢迎大家,加入我 ...