Zookeeper
每个子目录项如 NameService 都被称作为 znode(目录节点),和文件系统一样,我们能够自由的增加、删除znode,在一个znode下增加、删除子znode,唯一的不同在于znode是可以存储数据的。
假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦,现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。
引入依赖
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
</dependencies>
创建节点
/**
* 节点创建
* 1.创客户端
* 2.客户端发命令
* 3.返回结果
* 4.回收资源
*/
public static void create() throws IOException,InterruptedException,KeeperException {
//创客户端 1000是session超时时间
ZooKeeper zooKeeper=new ZooKeeper("你的IP:你的端口", 10000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("watch方法在执行中");
}
});
//创建节点 ZooDefs.Ids.CREATOR_ALL_ACL默认权限
String res = zooKeeper.create("/parent", "parent data".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("创建parent节点结果:"+res);
//创建临时节点
String tempRes = zooKeeper.create("/parent/temp", null,
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
System.out.println("创建parent临时节点结果:"+res);
//创建带序号节点
String seqRes = zooKeeper.create("/parent/sequence", null,
ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
System.out.println("创建parent带序号节点结果:"+res);
Thread.sleep(6000);
zooKeeper.close();
}
重点关注:zooKeeper.create()方法
查询节点
1、查询根节点下的节点(只有/xx 一级目录的节点)
public static void list() throws Exception{
//创客户端
ZooKeeper zooKeeper=new ZooKeeper("你的IP:端口", 10000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("watch方法在执行中");
}
});
//遍历zk所有根节点
List<String> children = zooKeeper.getChildren("/", false);
children.forEach(System.out::println);
}
2、查询某个节点下的所有节点
/**
* 遍历zk所有节点
* @param zooKeeper
* @param path
* @throws Exception
*/
private static void listAll(ZooKeeper zooKeeper,String path)throws Exception{
List<String> children = zooKeeper.getChildren(path, false);
for (String child:children){
String current="/".equals(path)?(path+child):path+"/"+child;
System.out.println(current);
listAll(zooKeeper,current);
}
}
如果是根节点”/“ :后续节点直接加子节点
不是根节点的 eg:"/parent":后续节点要加”/“和子节点
3、查询某个节点的值
/**
* 查询节点中的值,根据Key获得Value
* @throws Exception
*/
public static void query() throws Exception{
//创客户端
ZooKeeper zooKeeper=new ZooKeeper("你的IP:端口号", 10000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("watch方法在执行中");
}
});
//获得节点数据
byte[] data = zooKeeper.getData("/parent", false, null);
System.out.println("节点数据是:"+new String(data));
}
重点关注:zooKeeper.getData()
删除某个节点
public static void delete() throws Exception{
//创客户端
ZooKeeper zooKeeper=new ZooKeeper("120.24.240.192:2181", 10000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("watch方法在执行中");
}
});
Stat stat = new Stat();
System.out.println(stat.getCversion());
zooKeeper.getData("/parent/sequence0000000001",false,stat);
System.out.println(stat.getCversion());
zooKeeper.delete("/parent/sequence0000000001",stat.getCversion());
}
getData()
public byte[] getData(String path, boolean watch, Stat stat) throws KeeperException, InterruptedException {
return this.getData(path, watch ? this.watchManager.defaultWatcher : null, stat);
}
路径、是否监视、状态
状态Stat:new Stat()后 用getCversion()方法,获取当前的Cversion,删除时凭Cversion删除