package com.baidu.disconf.core.common.zookeeper; import java.io.IOException; import java.util.List; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.baidu.disconf.core.common.utils.ZooUtils; import com.baidu.disconf.core.common.zookeeper.inner.ResilientActiveKeyValueStore; /** * ZK统一管理器 * * @author liaoqiqi * @version 2014-7-7 */ public class ZookeeperMgr { protected static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperMgr.class); private ResilientActiveKeyValueStore store; private String curHost = ""; private String curDefaultPrefixString = ""; /** * @return void * * @throws Exception * @Description: 初始化 * @author liaoqiqi * @date 2013-6-14 */ public void init(String host, String defaultPrefixString, boolean debug) throws Exception { try { initInternal(host, defaultPrefixString, debug); LOGGER.debug("ZookeeperMgr init."); } catch (Exception e) { throw new Exception("zookeeper init failed. ", e); } } /** * 建立连接 */ private ZookeeperMgr() { } /** * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例 没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。 */ private static class SingletonHolder { /** * 静态初始化器,由JVM来保证线程安全 */ private static ZookeeperMgr instance = new ZookeeperMgr(); } public static ZookeeperMgr getInstance() { return SingletonHolder.instance; } /** * 重新连接 */ public void reconnect() { store.reconnect(); } /** * @return void * * @throws IOException * @throws InterruptedException * @Description: 初始化 * @author liaoqiqi * @date 2013-6-14 */ private void initInternal(String hosts, String defaultPrefixString, boolean debug) throws IOException, InterruptedException { curHost = hosts; curDefaultPrefixString = defaultPrefixString; store = new ResilientActiveKeyValueStore(debug); store.connect(hosts); LOGGER.info("zoo prefix: " + defaultPrefixString); // 新建父目录 makeDir(defaultPrefixString, ZooUtils.getIp()); } /** * Zoo的新建目录 * * @param dir */ public void makeDir(String dir, String data) { try { boolean deafult_path_exist = store.exists(dir); if (!deafult_path_exist) { LOGGER.info("create: " + dir); this.writePersistentUrl(dir, data); } else { } } catch (KeeperException e) { LOGGER.error("cannot create path: " + dir, e); } catch (Exception e) { LOGGER.error("cannot create path: " + dir, e); } } /** * @return void * * @Description: 应用程序必须调用它来释放zookeeper资源 * @author liaoqiqi * @date 2013-6-14 */ public void release() throws InterruptedException { store.close(); } /** * @return List<String> * * @Description: 获取子孩子 列表 * @author liaoqiqi * @date 2013-6-14 */ public List<String> getRootChildren() { return store.getRootChildren(); } /** * @return List<String> * * @Description: 写持久化结点, 没有则新建, 存在则进行更新 * @author liaoqiqi * @date 2013-6-14 */ public void writePersistentUrl(String url, String value) throws Exception { store.write(url, value); } /** * @return List<String> * * @Description: 读结点数据 * @author liaoqiqi * @date 2013-6-14 */ public String readUrl(String url, Watcher watcher) throws Exception { return store.read(url, watcher, null); } /* * 返回zk */ public ZooKeeper getZk() { return store.getZk(); } /* * 路径是否存在 */ public boolean exists(String path) throws Exception { return store.exists(path); } /* * 生成一个临时结点 */ public String createEphemeralNode(String path, String value, CreateMode createMode) throws Exception { return store.createEphemeralNode(path, value, createMode); } /** * @param path * @param watcher * @param stat * * @return String * * @throws InterruptedException * @throws KeeperException * @Description: 带状态信息的读取数据 * @author liaoqiqi * @date 2013-6-17 */ public String read(String path, Watcher watcher, Stat stat) throws InterruptedException, KeeperException { return store.read(path, watcher, stat); } /** * @param path * * @return void * * @Description: 删除结点 * @author liaoqiqi * @date 2013-6-17 */ public void deleteNode(String path) { store.deleteNode(path); } }