1、Zookeeper使用的几点理解:
(1)、Zookeeper的节点只能一层一层的建立,不能一次建立多级节点;
(2)、关于Zookeeper常连接是指,从创建zookeeper对象到其被销毁的这个时间段内会保持与服务器的连接,主动调用close方法或代码执行结束,其连接就会断开;
2、实例说明:
模拟管理分布式服务发布和调用,通过在zookeeper上建立服务接口(全类路径)为节点,服务提供者IP为子节点,服务调用者监听服务接口节点获取服务提供这对应的IP列表(子节点列表)
1、接口定义
public interface IHelloZookeeperService {
public String sayHello(String name);
}
2、服务发布
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);
}
}
}
3、服务发布主函数
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();
}
}
}
}
4、服务消费
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);
}
}
5、服务消费主函数
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) {
}
}
}
}
6、使用常量类
public interface Zookeepers{
String ZK_CONNECTIED_URL="10.28.163.32:2181";
int ZK_SESSION_TIMEOUT=5000;
String ZK_ROOT_PATH="/registryroot";
}