ZooKeeper提供的Java API.每一个方法有一个异步调用版本。异步调用和同步调用的区别之处:同步调用中,需要处理异常。异步调用中已经把异常封装为返回码。 同时异步调用会得到更好的性能。这里要注意,一般来说异步调用会在命令发送到Zookeeper服务器之前,就返回继续执行之后的代码。
推荐使用异步方法访问Zookeeper,除了可以简化异常处理,提高性能外。还应为Watcher的处理是异常的。这样在构建复杂逻辑时,代码会更统一些。
创建节点
AsyncCallback.StringCallback createCallback = new AsyncCallback.StringCallback() {
@Override
public void processResult(int rc, String path, Object ctx, String name) {
switch (KeeperException.Code.get(rc)){
case CONNECTIONLOSS:
runForMaster();
break;
case NODEEXISTS:
break;
case OK:
break;
default:
LOG.error("Something went wrong when running for master.",
KeeperException.create(KeeperException.Code.get(rc), path));
}
}
};
public void runForMaster(){
zk.create("/master","master".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL, createCallback,null);
}
注意下 回调方法中的代码,所有的回调方法都需要这样处理。CONNECTIONLOSS 表示网络异常,一般都需要重试。同时也要考虑节点存在或不存在的情况。
读取节点
AsyncCallback.DataCallback getDataCallback = new AsyncCallback.DataCallback() {
@Override
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
switch (KeeperException.Code.get(rc)) {
case CONNECTIONLOSS:
checkMaster();
break;
case NONODE:
LOG.error("Node {} not Exist ",
path, KeeperException.create(KeeperException.Code.get(rc), path));
break;
case OK:
break;
default:
LOG.error("Something went wrong when running for master.",
KeeperException.create(KeeperException.Code.get(rc), path));
}
}
};
public void checkMaster(){
zk.getData("/master",false, getDataCallback, null);
}