zookeeper原生API与zkClient的使用

原生API

首先导入jar包:

 <dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.8</version>
</dependency>

1.建立session会话

public class CreateSessionDemo {
	//zookeeper集群地址
    private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
    //并发包中的计数器
    private static CountDownLatch countDownLatch=new CountDownLatch(1);
    public static void main(String[] args) throws IOException, InterruptedException {
    	//5000 session过期时间   超过5秒连接会断掉
    	//watcher 监控机制  
        ZooKeeper zooKeeper=new ZooKeeper(CONNECTSTRING, 5000, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                //如果当前的连接状态是连接成功的,那么通过计数器去控制 计数器-1
                if(watchedEvent.getState()==Event.KeeperState.SyncConnected){
                    countDownLatch.countDown();
                    System.out.println(watchedEvent.getState());
                }
            }
        });
        
        countDownLatch.await();  //调用await的线程会被挂起  直到CountDownLatch中的值为0
        System.out.println(zooKeeper.getState());
    }
}

运行结果:

名词解析:

createMode类型解析:

persistent 持久化节点

persistent sequential 持久化有序节点

ephemeral 临时节点

ephemeral sequential 临时有序节点 

这个其实就对应了命令行中的:create -s -e path data acl   中的-s和-e

ZooDefs.Ids解析:

看下么源码图与命令行图,可以看出其实就是对权限控制的封装。

源码图:

命令行图:

2.创建节点与监听

public class ApiOperatorDemo implements Watcher{
	//连接地址及端口号
	private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
	//并发包工具类
	private static CountDownLatch countDownLatch = new CountDownLatch(1);
	private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
	private static ZooKeeper zooKeeper;
	//节点状态信息
	private static Stat stat = new Stat();
	public static void main(String[] args) throws Exception{
		 zooKeeper = new ZooKeeper(CONNECTSTRING, 10000, new ApiOperatorDemo());
		 countDownLatch.await();
		 //使用exists给createTest节点创建监听,并返回stat,stat为空则表示当前节点不存在
		 Stat stat = zooKeeper.exists("/createTest",true);
		 //创建节点
		 zooKeeper.create("/createTest","test".getBytes(),ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
		 //这里需要让main线程sleep一下或者await一下,如果不sleep会导致main执行完成,但是服务端向客户端发送的watch通知还没到达
		 // Thread.sleep(2000);
		 countDownLatch2.await();
		
		 //创建子节点  子节点与上面类似  只有一点需要注意,就是父节点必须是持久化节点不能是临时节点 。临时节点不能有子节点。
	   }
	 
	public void process(WatchedEvent watchedEvent) {
		//如果当前的连接状态是连接成功的,那么通过计数器去控制
		if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
			//第一次进来的连接状态
			if(Event.EventType.None==watchedEvent.getType()&&null==watchedEvent.getPath()){
                countDownLatch.countDown();
                System.out.println(watchedEvent.getState()+"-->"+watchedEvent.getType());
            }
			//创建子节点的时候会触发
			else if(watchedEvent.getType()== Event.EventType.NodeCreated){
                try {
                	 //通过路径获取数据将数据存储在stat中,true表示再注册一次通知,因为通知是一次失效的
                	byte[] data = zooKeeper.getData(watchedEvent.getPath(),true,stat);
                	System.out.println("stat:"+stat);
                    System.out.println("节点创建路径:"+watchedEvent.getPath()+"->节点的值:"+data); 
                    countDownLatch2.countDown();
                } catch (KeeperException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
		}
	}
}

运行结果:

修改节点与监听:

public class ApiOperatorDemo implements Watcher{
	//连接地址及端口号
		private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
		//并发包工具类
		private static CountDownLatch countDownLatch = new CountDownLatch(1);
		private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
		private static ZooKeeper zooKeeper;
		//节点状态信息
		private static Stat stat = new Stat();
		public static void main(String[] args) throws Exception{
			 zooKeeper = new ZooKeeper(CONNECTSTRING, 10000, new ApiOperatorDemo());
			 countDownLatch.await();
			 
			 //使用exist给createTest节点创建监听,并返回stat,stat为空则表示当前节点不存在
			 // Stat stat = zooKeeper.exists("/createTest",true);
			 //或者getData给createTest节点创建监听
			 zooKeeper.getData("/createTest",true, stat);
			 //修改节点  -1表示不用管版本号
			 zooKeeper.setData("/createTest","test2".getBytes(), -1);
			 //这里需要让main线程sleep一下或者await一下,如果不sleep会导致main执行完成,但是服务端向客户端发送的watch通知还没到达
			 // Thread.sleep(2000);
			 countDownLatch2.await();
			
			 //创建子节点  子节点与上面类似  只有一点需要注意,就是父节点必须是持久化节点不能是临时节点 。临时节点不能有子节点。
		   }
		 
		public void process(WatchedEvent watchedEvent) {
			//如果当前的连接状态是连接成功的,那么通过计数器去控制
			if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
				//第一次进来的连接状态
				if(Event.EventType.None==watchedEvent.getType()&&null==watchedEvent.getPath()){
	              countDownLatch.countDown();
	              System.out.println(watchedEvent.getState()+"-->"+watchedEvent.getType());
	          }
				//创建子节点的时候会触发
				else if(watchedEvent.getType()== Event.EventType.NodeDataChanged){
	              try {
	              	 //通过路径获取数据将数据存储在stat中,true表示再注册一次通知,因为通知是一次失效的
	              	byte[] data = zooKeeper.getData(watchedEvent.getPath(),true,stat);
	              	System.out.println("stat:"+stat);
	                  System.out.println("节点数据变更路径:"+watchedEvent.getPath()+"->节点的值:"+new String(data)); 
	                  countDownLatch2.countDown();
	              } catch (KeeperException e) {
	                  e.printStackTrace();
	              } catch (InterruptedException e) {
	                  e.printStackTrace();
	              }
	          }
			}
		}
}

运行结果:

删除节点与监听:

public class ApiOperatorDemo implements Watcher{
	//连接地址及端口号
		private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
		//并发包工具类
		private static CountDownLatch countDownLatch = new CountDownLatch(1);
		private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
		private static ZooKeeper zooKeeper;
		//节点状态信息
		private static Stat stat = new Stat();
		public static void main(String[] args) throws Exception{
			 zooKeeper = new ZooKeeper(CONNECTSTRING, 10000, new ApiOperatorDemo());
			 countDownLatch.await();
			 
			 //使用exist给createTest节点创建监听,并返回stat,stat为空则表示当前节点不存在
			 // Stat stat = zooKeeper.exists("/createTest",true);
			 //或者getData给createTest节点创建监听
			 zooKeeper.getData("/createTest",true, stat);
			//删除节点
			 zooKeeper.delete("/createTest", -1);
			 //这里需要让main线程sleep一下或者await一下,如果不sleep会导致main执行完成,但是服务端向客户端发送的watch通知还没到达
			 // Thread.sleep(2000);
			 countDownLatch2.await();
			
			 //创建子节点  子节点与上面类似  只有一点需要注意,就是父节点必须是持久化节点不能是临时节点 。临时节点不能有子节点。
		   }
		 
		public void process(WatchedEvent watchedEvent) {
			//如果当前的连接状态是连接成功的,那么通过计数器去控制
			if(watchedEvent.getState() == Event.KeeperState.SyncConnected){
				//第一次进来的连接状态
				if(Event.EventType.None==watchedEvent.getType()&&null==watchedEvent.getPath()){
	              countDownLatch.countDown();
	              System.out.println(watchedEvent.getState()+"-->"+watchedEvent.getType());
	          }
				//删除子节点的时候会触发
				else if(watchedEvent.getType()== Event.EventType.NodeDeleted){
	          
	            	  System.out.println("节点删除路径:"+watchedEvent.getPath()); 
	                  countDownLatch2.countDown();
	              
	          }
			}
		}
}

运行结果:

zkClient的使用:

创建会话: 比原生的简单多了

public class SessionDemo {
	private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
	public static void main(String[] args) {
		ZkClient zkClient = new ZkClient(CONNECTSTRING,4000);
		
		System.out.println(zkClient+"--->SUCCESS");
		
	}
}

基本操作:zkClient递归创建父节点,监控节点,修改节点:

public class ZKClientApiOperatorDemo {
	
	private final static String CONNECTSTRING="192.168.74.131:2181,192.168.74.132:2181,192.168.74.133:2181";
	public static void main(String[] args) throws Exception {
		ZkClient zkClient = new ZkClient(CONNECTSTRING,4000);
		System.out.println(zkClient+"--->SUCCESS");
		
		//zkCLient提供递归创建父节点的功能
		zkClient.createPersistent("/zkclient/zkclient1/zkclient1-1/zkclient1-1-1",true);
		
		//获取子节点
		List<String> children = zkClient.getChildren("/zkclient");
		System.out.println("children:"+children);
		
		//watcher
		zkClient.subscribeDataChanges("/zkclient",new IZkDataListener() {
			
			public void handleDataDeleted(String dataPath) throws Exception {
				// TODO Auto-generated method stub
				
			}
			
			public void handleDataChange(String dataPath, Object data) throws Exception {
				// TODO Auto-generated method stub
				System.out.println("节点名称:"+dataPath+"->节点修改后的值"+data);
			}
			
		});
		zkClient.writeData("/zkclient", "123");
		TimeUnit.SECONDS.sleep(2);

	}
	
}

猜你喜欢

转载自blog.csdn.net/qq_37113604/article/details/89348718