一、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"; }