Zookeeper提供了Java API方便我们来操作zk服务,可以通过maven引入zk的相关依赖包。通过org.apache.zookeeper.Zookeeper类创建连接zk服务器的示例对象,在创建过程中给定zk服务器地址、会话持续时间以及监视器三个参数,当连接创建成功后,通过Zookeeper实例提供的接口来和服务器进行交互。Pom文件依赖内容如下:
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.5</version>
(一)创建连接
使用Zookeeper类来表示连接,创建的该实例对象有四个构造方法来调用,不过一般最常用的是下面两个构造方法的调用:ZooKeeper(connectString,session-Timeout,watcher)和ZooKeeper(connectString,sessionTimeout,watcher,canBeRead-Only);其中第一个构造方式底层调用第二个构造方法,只是canBeReadOnly参数设置为false。connectString参数为zk集群服务器的连接url,当给定路径的时候,表示所有的操作都是基于该路径进行操作的(路径只可以添加到最后)。例如: “hh:2181,hh:2182,hh:2183/app”;sessionTimeout为会话过期时间,一般设置为tickTime的3-4倍;watcher是监视器,用于触发相应事件,可以为空;canBeReadOnly是给定是否是只读连接,默认为false。
import org.apache.zookeeper.Zookeeper;
...
// 创建连接,第一个参数可以只有IP地址列表,采用默认端口2181
Zookeeper client = new Zookeeper(“hh:2181,hh:2182,hh:2183”, 4000, null);
// 其实url的格式为: ip[:port](,ip[:port])*[/path]
...
client.close(); // 关闭连接
(二)新增/创建节点
ZK中新增子节点和创建节点其实是同一个含义,创建一个节点其实就相当于在根目录下新增一个子节点,zk不支持为不存在的父节点创建子节点(不支持循环创建)。创建节点的时候要求指明节点被创建的类型(CreateMode)。调用Zookeeper实例的create方法,需要给定的参数有:path(节点路径), data(数据), acl(控制权限列表,不考虑权限的情况下给定为: Ids.OPEN_ACL_UNSAFE), createMode(节点类型)。
节点类型
.....// 初始化client
// 创建一个新节点root,数据为data,类型为永久节点
client.create("/root", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 给root节点添加一个子节点
client.create("/root/child", "child_data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
....// 关闭client
(三)删除节点
当系统不需要某个配置节点的时候,或者某个节点失效的时候,使用delete方法可以删除该节点,删除要求是:被删除的节点没有子节点,而且被删除的节点存在,并且需要给定明确的版本号(可以给定-1,表示不管版本号是什么都删除)。代码如下:
client.delete(“/root/child”, -1); // 不管版本号直接删除
client.delete(“/root”, 0); // 直接删除版本号为0的root节点,如果zk上root节点的版本是0,那么删除成功,否则抛出异常
(四)设置节点内容
当节点内容需要进行改变的时候可以调用setData方法设置节点内容,设置内容的时候也需要给定版本号,zk服务器会检查该版本号,如果当前节点和你给定的版本号不一致,那么直接抛出异常,否则更新成功。如果给定的版本号为-1,那么表示不检查。代码如下:
client.setData("/root/child", "new-data".getBytes(), -1); // 设置新的内容
(五)获取节点内容
当应用系统需要读取zk节点的内容的时候可以调用getData方法直接获取节点设置的内容/数据。该方法有四个重载方法,一般情况下直接调用第一个方法即可,代码如下:
// 获取数据,不进行watch机制监控,state状态信息为空
String data = new String(client.getData("/root/child", false, null));
System.out.println(data);
(六)Watch机制
Watch机制是zk中一种类似observer的机制,当节点发生变化的时候,会通知watch定义的方法。当发生变化的时候,zk服务器会发送一次且仅一次通知信息给客户端(以节点和watcher为计算单位,也就是说同一个节点,不同方法上使用同一个监视器(watcher实例)只会触发一次)。如果使用该机制需要自定义实现org.apache.zookeeper.Watcher接口的process方法,该方法传入一个org.apache.zookeeper.WatchedEvent的event参数。其中event中主要包含一个改变原因以及对应监视节点的路径。只有exits、getChildren和getData三个方法上可以指定监视器。
总结:
1. 同一个node,同一个watcher实例,zk服务器只会通知一次。
2. watch的触发有不同的触发规则,不同的方法只会触发不同类型的event。
3. watch机制只监控node节点本身以及node节点的第一代子节点。
4. 指定watch参数的时候,如果指定的是true,那么表示使用默认的watch实例对象,即在创建连接的时候给定的watch实例对象。
来源:https://blog.csdn.net/weixin_41850738/article/details/100085586