一、Zookeeper使用的幾點理解:java
(1)、Zookeeper的節點只能一層一層的創建,不能一次創建多級節點;
node
(2)、關於Zookeeper常鏈接是指,從建立zookeeper對象到其被銷燬的這個時間段內會保持與服務器的鏈接,主動調用close方法或代碼執行結束,其鏈接就會斷開;api
二、實例說明:服務器
模擬管理分佈式服務發佈和調用,經過在zookeeper上創建服務接口(全類路徑)爲節點,服務提供者IP爲子節點,服務調用者監聽服務接口節點獲取服務提供這對應的IP列表(子節點列表)分佈式
一、接口定義ide
public interface IHelloZookeeperService { public String sayHello(String name); }
二、服務發佈函數
public class ZkServerProvider { private Logger log = LoggerFactory.getLogger(ZkServerProvider.class); private ZooKeeper zk = null; public ZkServerProvider(){ zk = ZookeeperUtils.connectServer(JccConst.Zookeepers.ZK_CONNECTIED_URL); //建立根節點 Stat exists; try { exists = zk.exists(JccConst.Zookeepers.ZK_ROOT_PATH, false); if(exists == null){ createNode(JccConst.Zookeepers.ZK_ROOT_PATH, "root node".getBytes(), CreateMode.PERSISTENT); } } catch (Exception e) { log.error("判斷節點是否存在",e); } } public void registerServer(String fullMethodPath,String serverIp){ String pathMethod = JccConst.Zookeepers.ZK_ROOT_PATH+"/"+fullMethodPath; try { if(zk.exists(pathMethod, true)==null){ createNode(pathMethod, pathMethod.getBytes(), CreateMode.PERSISTENT); } String serverPath= pathMethod +"/"+serverIp; if(zk.exists(serverPath, true)==null){ createNode(serverPath, serverPath.getBytes(), CreateMode.EPHEMERAL); } } catch (Exception e) { log.error("發佈服務",e); } } public void createNode(String path,byte[] data,CreateMode createMode){ try{ String create = zk.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode); log.info("create node realpath="+create); }catch(Exception e){ log.error("--建立節點錯誤",e); } } }
三、服務發佈主函數code
import org.jccdemo.api.zookeeper.IHelloZookeeperService; public class ZkServerMain { public static void main(String[] args) { ZkServerProvider sp = new ZkServerProvider(); for (int i = 0; i < 15; i++) { sp.registerServer(IHelloZookeeperService.class.getName(), "1111."+i); System.out.println(i + ",服務發佈完成...."); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
四、服務消費server
public class ZkServerConsumer { private Logger log = LoggerFactory.getLogger(ZkServerConsumer.class); private ZooKeeper zk = null; private Map<String,List<String>> map = new HashMap<String,List<String>>(); public ZkServerConsumer(){ zk = ZookeeperUtils.connectServer(JccConst.Zookeepers.ZK_CONNECTIED_URL); } public void setNodeWather(String fullPath){ setWatcher(fullPath); } private void setWatcher(final String fullPath){ try { List<String> children = zk.getChildren(fullPath, new Watcher(){ public void process(WatchedEvent event) { log.info("執行節點Wathcer事件"); if(event.getType() == Event.EventType.NodeChildrenChanged){ setWatcher(fullPath); } } }); map.put(fullPath, children); log.info("children="+children); } catch (Exception e) { log.error("獲取子節點錯誤",e); } } public List<String> lookup(String fullPath){ return map.get(fullPath); } }
五、服務消費主函數對象
public class ZkClientMain { public static void main(String[] args) { ZkServerConsumer consumer = new ZkServerConsumer(); String fullPath = JccConst.Zookeepers.ZK_ROOT_PATH + "/" + IHelloZookeeperService.class.getName(); consumer.setNodeWather(fullPath); for (int i = 0; i < 10; i++) { List<String> list = consumer.lookup(fullPath); System.out.println(i+"="+list); try { Thread.sleep(3000); } catch (InterruptedException e) { } } } }
六、使用常量類
public interface Zookeepers{ String ZK_CONNECTIED_URL="10.28.163.32:2181"; int ZK_SESSION_TIMEOUT=5000; String ZK_ROOT_PATH="/registryroot"; }