原生api
maven引入
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.8</version>
</dependency>
package zookeeper;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.util.List;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class CreateNodeDemo implements Watcher {
private final static String CONNECT_STRING = "192.168.36.128:2181,192.168.36.129:2181,192.168.36.130:2181";
private static CountDownLatch countDownLatch = new CountDownLatch(1);
private static ZooKeeper zookeeper;
private static Stat stat = new Stat();
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zookeeper = new ZooKeeper(CONNECT_STRING, 5000, new CreateNodeDemo());
countDownLatch.await();
System.out.println(zookeeper.getState());
String result = zookeeper.create("/node1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
zookeeper.getData("/node1", new CreateNodeDemo(), stat);//添加监听
//修改数据
zookeeper.setData("/node1", "node123".getBytes(), -1);//-1是不管版本号
Thread.sleep(2000);
System.out.println(result);
zookeeper.setData("/node1","345".getBytes(),-1);
Thread.sleep(2000);
//删除node
zookeeper.delete("/del/del1",-1);
Thread.sleep(2000);
//创建子节点
String path = "/nodes2";
Stat st = zookeeper.exists(path,true);
if(st==null){
//节点不存在
zookeeper.create(path, "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
TimeUnit.SECONDS.sleep(1);
}
Stat st1 = zookeeper.exists(path+"/node1",true);
if(st1==null){
//节点不存在
zookeeper.create(path+"/node1", "123".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
TimeUnit.SECONDS.sleep(1);
}
TimeUnit.SECONDS.sleep(1);
//修改子路径
zookeeper.setData(path+"/node1","mic123".getBytes(),-1);
TimeUnit.SECONDS.sleep(1);
//获取子节点
List<String> children = zookeeper.getChildren("nod/e",true);
}
public void process(WatchedEvent watchedEvent) {
if (watchedEvent.getState() == Event.KeeperState.SyncConnected) {
if(Event.EventType.None==watchedEvent.getType()&&watchedEvent.getPath()==null){
countDownLatch.countDown();
System.out.println(watchedEvent.getType()+"-----"+watchedEvent.getPath());
}else if (watchedEvent.getType() == Event.EventType.NodeDataChanged) {
try {
System.out.println("路径" + watchedEvent.getPath() + "-->数据变更:" + zookeeper.getData(watchedEvent.getPath(), true, stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
try {
System.out.println("路径" + watchedEvent.getPath() + "-->子节点变更:" + zookeeper.getData(watchedEvent.getPath(), true, stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (watchedEvent.getType() == Event.EventType.NodeCreated) {
try {
System.out.println("路径" + watchedEvent.getPath() + "-->节点创建:" + zookeeper.getData(watchedEvent.getPath(), true, stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (watchedEvent.getType() == Event.EventType.NodeDeleted) {
try {
System.out.println("路径" + watchedEvent.getPath() + "-->节点删除:" + zookeeper.getData(watchedEvent.getPath(), true, stat));
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println(watchedEvent.getType());
}
}
权限控制
权限控制模式有:
- schema:授权对象
- ip :ip
- Digest:账号、密码
- world :开放式的权限控制模式,数据节点的访问权限对所有用户开放。
- super:超级用户,可以对zookeeper上的数据节点进行操作
连接状态
KeeperStat.Expired:在一定时间内客户端没有收到服务器的通知,则认为当前回话已经过期
KeeperStat.Disconnected: 断开连接的状态
KeeperStat.SyncConnected: 客户端与服务器在某一个节点上建立连接,并完成一次version、zxid同步
KeeperStat.authFailed: 授权失败
事件类型
NodeCreated:节点创建时触发
NodeChildrenChanged:子节点创建、删除、数据发生变化时触发
NodeDataChanged:节点数据发生变化触发
NodeDeleted:节点删除触发
None:客户端与服务器连接状态发生改变时触发
zkclient
ZkClient是基于zookeeper原生api进行封装的框架,简化了一定的操作。但是最常用的还是下面的Curator。
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
package zkClient;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
public class ZkClientDemo {
public static void main(String[] args) {
ZkClient zkClient = new ZkClient("",5000);
zkClient.createPersistent("");
//递归创建
zkClient.createPersistent("",true);
//递归删除
zkClient.deleteRecursive("");
//修改
zkClient.writeData("","data");
//订阅节点信息
zkClient.subscribeDataChanges("", new IZkDataListener() {
public void handleDataChange(String s, Object o) throws Exception {
}
public void handleDataDeleted(String s) throws Exception {
}
});
}
}
Curator
Curator是Netflix公司的开源zookeeper产品,Eureka也是这家公司的。Curator提供了各种应用场景的实现。
包括两个模块:
curator-framework
curator-recipes
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>2.11.0</version>
</dependency>