异步实现主节点选举
Zookeeper中,所有同步调用方法都有对应的异步调用方法,通过异步调用,我们可以在单线程中同时进行多个调用,接下来实现一个异步实现主节点选举的例子
Zookeeper.create方法的异步调用版本
void create(String path, byte data[], List acl, CreateMode createMode, AsyncCallback.StringCallback cb,Object ctx) ,相较于同步调用,多了StringCallback ,和Object两个参数。StringCallback 提供回调方法的对象,Object用户指定上下文信息
代码示例
package com.my.service;
import java.io.IOException;
import java.util.Random;
import org.apache.zookeeper.AsyncCallback.DataCallback;
import org.apache.zookeeper.AsyncCallback.StringCallback;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
public class MyZookeeper {
private ZooKeeper zooKeeper;
private String hostPort;
private Random random = new Random(47);
private String serverId = Integer.toString(random.nextInt());
boolean isMaster = false;
public MyZookeeper(String hostPort) {
this.hostPort = hostPort;
}
// 创建一个zk连接监视点,打印断开连接日志信息
Watcher watcher = new Watcher() {
public void process(WatchedEvent event) {
// 如果监控到与服务端连接断开,打印日志
if (KeeperState.Disconnected.equals(event.getState())) {
System.out.println("Zookeeper Disconnected!客户端与ZooKeeper服务器连接断开!");
}
}
};
// 连接到zk服务端
public void startZk() throws IOException {
zooKeeper = new ZooKeeper(hostPort, 15000, watcher);
}
public void stopZk() throws InterruptedException {
zooKeeper.close();
}
// 实现一个回调的接口,并创建实例
StringCallback masterCallback = new StringCallback() {
public void processResult(int rc, String path, Object ctx, String name) {
switch (Code.get(rc)) {// rc返回调用的结构,返回OK或与KeeperException异常对应的编码值
case CONNECTIONLOSS:
checkMasterSync();
return;
case OK:
//创建成功,成为主节点
isMaster = true;
break;
default:
isMaster = false;
}
System.out.println("I am" + (isMaster ? "" : "not") + " the master");
}
};
// 实现一个检查数据的回调接口,并创建实例
DataCallback masterCheckCallBack = new DataCallback() {
public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
switch (Code.get(rc)) {
case CONNECTIONLOSS:
checkMasterSync();
return;
case NONODE:
//主节点不存在,进行异步主节点创建
runForMasterSync();
return;
}
}
};
public void checkMasterSync() {
zooKeeper.getData("/master", false, masterCheckCallBack, null);
}
public void runForMasterSync() {
zooKeeper.create("/master", serverId.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL,
masterCallback, null);
}
public static void main(String[] args) throws IOException, InterruptedException {
MyZookeeper myZookeeper = new MyZookeeper("127.0.0.1:2181");
myZookeeper.startZk();
myZookeeper.runForMasterSync();
//线程休眠一段时间,观看异步创建效果
Thread.sleep(5000);
if (myZookeeper.isMaster) {
System.out.println("我是主节点");
Thread.sleep(60000);
} else {
System.out.println("其他节点已经成为了主节点");
}
}
}