为了完成本关任务,你需要掌握: 1.同步调用和异步调用区别; 2.节点创建 API 使用; 3.节点删除 API 使用。
同步调用和异步调用
ZooKeeper 提供的 API 操作有异步调用和同步调用两种,区别在于:
同步调用需要处理异常;
异步调用已经把异常封装为返回码。一般来说异步调用会在命令发送到 Zookeeper 服务器之前,就返回继续执行之后的代码。
推荐使用异步调用方法,不但可以获得更好的性能,更可以统一编码风格,免去对异常的处理。同时,即使方法调用失败,回调函数仍然会继续调用失败的方法,直到返回正确的返回码。
节点创建 API 的使用
节点创建 API 分为同步和异步创建两种方式:
一、 同步调用节点创建方法:
public String create(final String path, byte data[], List<ACL> acl, CreateMode createMode) throws KeeperException, InterruptedException
上述方法的参数含义如下所示:
1、path:创建节点的路径;
2、data[]:创建节点的数据值,参数类型是字节数组;
3、acl:节点的访问权限。主要有以下几种类型:
- ANYONE_ID_UNSAFE:任何人;
- AUTH_IDS:只用来授权;
- OPEN_ACL_UNSAFE:开放的 ACL;
- CREATOR_ALL_ACL:创建 ACL;
- READ_ACL_UNSAFE: 所有人可读。
4、createMode:节点类型。主要有以下几种类型:
- PERSISTENT:持久;
- PERSISTENT_SEQUENTIAL:持久顺序;
- EPHEMERAL:临时;
- EPHEMERAL_SEQUENTIAL:临时顺序。
同步创建临时节点示例:
String ephemeralPath = zooKeeper.create("/zk-test-create-ephemeral", "ephemeral".getBytes(), ZooDefs.Ids.ANYONE_ID_UNSAFE, CreateMode.EPHEMERAL);
上述语句可用于创建一个临时节点 /zk-test-create-ephemeral,节点数据为"ephemeral",该节点的访问权限为任何人。
二、异步调用节点创建方法:
public void create(final String path, byte data[], List<ACL> acl, CreateMode createMode, StringCallback cb, Object ctx)
同步创建方法的参数异步方法都有,除此之外,它还有以下两个特有的:
异步创建临时顺序节点:
zooKeeper.create("/zk-test-create-async-sequential","async-sequential".getBytes(), ZooDefs.Ids.ANYONE_ID_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,new MyStringCallBack(),"CreateNode");
上述语句可用于创建一个临时顺序节点 /zk-test-create-async-sequential,节点数据为"async-sequential",节点的访问权限为任何人,节点上下文信息为“CreateNode”,节点的回调函数为我们自己创建的 MyStringCallBack 对象。
同步和异步节点创建示例:
- import org.apache.zookeeper.*;
- import java.io.IOException;
-
- public class MyTest {
- private ZooKeeper zk;
- // 实现一个 Watcher
- private Watcher wh = new Watcher() {
- // 重写 process 方法
- public void process(WatchedEvent event) {
- System.out.println(event);
- }
- };
-
- // 连接 ZooKeeper 服务器
- public void createZKInstance() throws IOException {
- zk = new ZooKeeper("localhost:2181", 15000, this.wh);
- }
-
- // 同步创建节点
- public String createNode() throws IOException, KeeperException, InterruptedException {
- String ephemeralPath = zk.create("/zk-test-create-ephemeral", "ephemeral".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- return ephemeralPath;
- }
-
- // 异步创建节点
- public void createNodeSync() throws KeeperException, InterruptedException{
- zk.create("/zk-test-create-async-sequential","async-sequential".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL,new MyStringCallBack(),"CreateNode");
- }
-
- public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
- MyTest myTest = new MyTest();
- // 连接 ZooKeeper 服务器
- myTest.createZKInstance();
- // 同步创建节点
- String node = myTest.createNode();
- // 输出节点
- System.out.println(node);
- // 异步创建节点
- myTest.createNodeSync();
- }
- // 回调函数
- public static class MyStringCallBack implements AsyncCallback.StringCallback{
- @Override
- public void processResult(int i, String s, Object o, String s1) {
- System.out.println(s);
- }
- }
-
- }
执行结果:
- WatchedEvent state:SyncConnected type:None path:null
- /zk-test-create-ephemeral
- /zk-test-create-async-sequential
上述代码中,我们使用同步方法创建了节点 /zk-test-create-ephemeral,使用异步方法创建了节点 /zk-test-create-async-sequential。
节点删除API使用
同样的,节点删除也有异步和同步两种方法,分别使用以下 API :
同步删除:
zk.delete(String path, int version);
异步删除:
zk.delete(String path, int version, StringCallback cb, Object ctx);
其中,version 表示不同的版本,可以通过 Stat 对象的 getVersion() 方法获取。如果该值为 -1,则忽略版本,将节点删除。
删除之前创建的节点示例:
- import org.apache.zookeeper.*;
- import java.io.IOException;
-
- public class MyTest {
- private ZooKeeper zk;
- // 实现一个 Watcher
- private Watcher wh = new Watcher() {
- // 重写 process 方法
- public void process(WatchedEvent event) {
- System.out.println(event);
- }
- };
-
- // 连接 ZooKeeper 服务器
- public void createZKInstance() throws IOException {
- zk = new ZooKeeper("localhost:2181", 15000, this.wh);
- }
-
- // 同步创建节点
- public String createNode() throws IOException, KeeperException, InterruptedException {
- String ephemeralPath = zk.create("/zk-test-create-ephemeral", "ephemeral".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
- return ephemeralPath;
- }
-
- // 同步删除节点
- public void deleteNode() throws IOException {
- zk.delete("/zk-test-create-ephemeral", -1);;
- }
-
-
- public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
- MyTest myTest = new MyTest();
- // 连接 ZooKeeper 服务器
- myTest.createZKInstance();
- // 同步创建节点
- String node = myTest.createNode();
- // 输出节点
- System.out.println(node);
- // 同步删除节点
- myTest.deleteNode();
- }
- }
执行结果:
- WatchedEvent state:SyncConnected type:None path:null
- /zk-test-create-ephemeral
- WatchedEvent state:SyncConnected type:NodeDeleted path:/zk-test-create-ephemeral
上述代码中,我们使用 delete 方法删除了节点 /zk-test-create-ephemeral。返回的结果也显示“NodeDeleted”(节点被删除)。
编程要求
仔细阅读右侧编辑区内给出的代码框架及注释,在 Begin-End 间编写程序代码,实现以下需求:
- import org.apache.zookeeper.*;
-
- import java.io.IOException;
-
- public class Student {
- // 初始化 ZooKeeper 实例
- private ZooKeeper zk;
- // 实现一个 Watcher
- private Watcher wh = new Watcher() {
- // 重写 process 方法
- public void process(WatchedEvent event) {
- System.out.println(event);
- }
- };
-
- // 连接ZooKeeper服务器
- public ZooKeeper createZKInstance() throws IOException {
- zk = new ZooKeeper("localhost:2181", 15000, this.wh);
- return zk;
- }
-
- // 使用同步方式删除节点 /mynode1
- public void deleteNode() throws KeeperException, InterruptedException {
- // 请在此处编写代码
- /********* Begin *********/
- zk.delete("/mynode1", -1);;
- /********* End *********/
-
- }
-
- // 使用异步方式创建节点 /mynode1
- public void createNodeSync() {
- // 请在此处编写代码
- /********* Begin *********/
-
- zk.create("/mynode1","This node is mine!".getBytes(), ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT,new test.MyStringCallback(),"CreateMynode!");
- /********* End *********/
-
- }
-
- }