/*** zookeeper客户端
*@authortomsnail
* @date 2015年4月3日 上午10:15:11*/
public classZkClient {private static final Logger logger = LoggerFactory.getLogger(ZkClient.class);//用于等待 SyncConnected 事件触发后继续执行当前线程
private CountDownLatch latch = new CountDownLatch(1);//定义一个 volatile 成员变量,用于保存最新的 RMI 地址(考虑到该变量或许会被其它线程所修改,一旦修改后,该变量的值会影响到所有线程)
private volatile List dataList = new ArrayList();private Lock _lock = newReentrantLock();private staticZooKeeper zk;privateLBUrl lbUrl;publicZkClient(){this(newBasicLBUrl());
}//构造器
publicZkClient(LBUrl lbUrl) {this.lbUrl =lbUrl;
zk= connectServer(); //连接 ZooKeeper 服务器并获取 ZooKeeper 对象
watchNode();new Thread(newRunnable() {
@Overridepublic voidrun() {while (true) {try{
Thread.currentThread().sleep(3000);
}catch(InterruptedException e) {
e.printStackTrace();
}
_lock.lock();if (zk != null) {if(zk.getState().isAlive()&&zk.getState().isConnected()) {
_lock.unlock();continue;
}
}if(zk!=null){try{
zk.close();
}catch(InterruptedException e) {
e.printStackTrace();
}
zk= null;
}
zk=connectServer();
_lock.unlock();
}
}
}).start();
}//查找 URL 服务
publicString getUrl() {if (dataList!=null&&dataList.size()>0) {return this.lbUrl.getUrl(dataList);
}return null;
}public ListgetUrls(){returndataList;
}//连接 ZooKeeper 服务器
privateZooKeeper connectServer() {
ZooKeeper zk= null;try{
zk= new ZooKeeper(ZkInfoDefinition.zkUrl, ZkInfoDefinition.sessionTimeout, newWatcher() {
@Overridepublic voidprocess(WatchedEvent event) {if (event.getState() ==Event.KeeperState.SyncConnected) {
latch.countDown();//唤醒当前正在执行的线程
}
}
});
latch.await();//使当前线程处于等待状态
} catch(Exception e) {
logger.error("", e);
}returnzk;
}//观察 /registry 节点下所有子节点是否有变化
private voidwatchNode() {
_lock.lock();if(zk!=null&&zk.getState().isAlive()&&zk.getState().isConnected()){
}else{if(zk!=null){try{
zk.close();
}catch(InterruptedException e) {
e.printStackTrace();
}
zk= null;
}
zk=connectServer();
}try{
List nodeList = zk.getChildren(ZkInfoDefinition.zkPath, newWatcher() {
@Overridepublic voidprocess(WatchedEvent event) {if (event.getType() ==Event.EventType.NodeChildrenChanged) {
watchNode();//若子节点有变化,则重新调用该方法(为了获取最新子节点中的数据)
}
}
});
List dataList = new ArrayList(); //用于存放 /registry 所有子节点中的数据
for(String node : nodeList) {byte[] data = zk.getData(ZkInfoDefinition.zkPath + "/" + node, false, null); //获取 /registry 的子节点中的数据
dataList.add(newString(data));
}
logger.debug("node data: {}", dataList);this.dataList =dataList;
}catch(Exception e) {
logger.error("", e);
}
_lock.unlock();
}public static voidmain(String[] args) {
ZkClient client= newZkClient();
System.out.println(client.getUrl());
}
}