Zookeeper3:Java下的使用和zkcilent

0. 添加jar包

 

我这里由于是使用的之前搭建好的springboot框架,所以直接添加maven依赖

<!--引入zookeeper-->

<dependency>

<groupId>org.apache.zookeeper</groupId>

<artifactId>zookeeper</artifactId>

<version>3.3.6</version>

</dependency>

 

1. 创建连接

 

创建zookeeper连接类,该类用于提供zookeeper对象,值得注意的是zookeeper创建连接是异步进行的,也就是说在我们走完new Zookeeper()这一步,程序继续向下执行,但是zookeeper并不一定已经连接成功,所以我们这里使用CountDownLatch来阻塞当前进程,直到连接成功。

 

如何判断已经连接成功呢?我们在第一篇博客里面介绍过zookeeper的watcher机制,这里我们在new zookeeper对象时传入一个watcher,用来监控连接是否已经成功,该项操作需要我们传入一个实现了Watcher接口的类的对象,我这里使用匿名内部类来实现,通过判断状态来执行countDownLatch.countDown(),结束线程阻塞

	public class ZookeeperConnection {
	
	    private static ZooKeeper zoo;
	
	    static CountDownLatch countDownLatch=new CountDownLatch(1);
	
	    public static ZooKeeper connect(String host) throws IOException, InterruptedException {
	        if (zoo != null) {
	            return zoo;
	        }
	        zoo=new ZooKeeper(host, 5000, new Watcher() {
	            @Override
	            public void process(WatchedEvent watchedEvent) {
	                if (watchedEvent.getState()== Event.KeeperState.SyncConnected){
	                    countDownLatch.countDown();
	                }
	            }
	        });
	        countDownLatch.await();
	        return zoo;
	    }
	
	    public static void  close() throws InterruptedException {
	        zoo.close();
	    }
	}

2. 具体操作

	@Controller
	@RequestMapping("/zoo")
	public class ZooController {
	
	    ZooKeeper zooKeeper;
	    String path = "/test1";
	
	    /**
	     * 创建节点
	     *
	     * create(String path, byte[] data, List<ACL> acl, CreateMode createMode)
	     */
	    @RequestMapping("createZoo")
	    public String createZoo() throws IOException, InterruptedException, KeeperException {
	        zooKeeper = ZookeeperConnection.connect("127.0.0.1");
	        zooKeeper.create(path, "666".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
	        return "/index";
	    }
	
	    /**
	     * 判断节点是否存在
	     *
	     * exists(String path, boolean watcher)
	     */
	    @RequestMapping("existZoo")
	    public String existZoo() throws IOException, InterruptedException, KeeperException {
	        zooKeeper = ZookeeperConnection.connect("127.0.0.1");
	        Stat stat = zooKeeper.exists(path, true);
	        if (stat != null) {
	            System.out.println("stat = " + stat);
	            System.out.println("stat.getVersion() = " + stat.getVersion());
	        }
	        zooKeeper.close();
	        return "/index";
	    }
	
	    /**
	     * 获取节点数据
	     *
	     * getData(String path, boolean watch, Stat stat)
	     */
	    @RequestMapping("getDataZoo")
	    public String getDataZoo() throws IOException, InterruptedException, KeeperException {
	        zooKeeper = ZookeeperConnection.connect("127.0.0.1");
	        byte[] data = zooKeeper.getData(path, false, null);
	        System.out.println(new String(data));
	        zooKeeper.close();
	        return "/index";
	    }
	
	    /**
	     * 数据变更自动获取
	     * 
	     * getData(String path, Watcher watcher, Stat stat)
	     */
	    @RequestMapping("getDataZoo2")
	    public String getDataZoo2() throws IOException, InterruptedException, KeeperException {
	        final CountDownLatch countDownLatch = new CountDownLatch(1);
	        zooKeeper = ZookeeperConnection.connect("127.0.0.1");
	        byte[] data = zooKeeper.getData(path, new Watcher() {
	            @Override
	            public void process(WatchedEvent watchedEvent) {
	                if (Event.EventType.None == watchedEvent.getType()) {
	                    switch (watchedEvent.getState()) {
	                        case Expired:
	                            countDownLatch.countDown();
	                            break;
	                    }
	                } else {
	                    try {
	                        byte[] data1 = zooKeeper.getData(path, false, null);
	                        System.out.println("data1 = " + new String(data1));
	                        countDownLatch.countDown();
	                    } catch (KeeperException e) {
	                        e.printStackTrace();
	                    } catch (InterruptedException e) {
	                        e.printStackTrace();
	                    }
	                }
	            }
	        }, null);
	        return "/index";
	    }
	
	    /**
	     * 修改数据
	     *
	     * setData(String path, byte[] data, int version)
	     */
	    @RequestMapping("setDataZoo")
	    public String setDataZoo() throws IOException, InterruptedException, KeeperException {
	        zooKeeper = ZookeeperConnection.connect("127.0.0.1");
	        zooKeeper.setData(path, "999".getBytes(), zooKeeper.exists(path, true).getVersion());
	        return "/index";
	    }
	}

值得说明的是,watcher注册好后,使用一次就会失效,要想继续监听当前节点,就需要重新注册监听

3. zkCilent

 

通过上面的演示,我们已经知道了zookeeper的基本操作方法,但是这种官方提供的原生方法不仅使用起来麻烦,而且watcher用完即扔,想要再次使用还得重新注册,简直不要太麻烦!那么有没有一种好的工具让我们操作起来简单点呢?当然是有的了!  感谢开放的互联网平台,早就有大神帮我们造好了轮子,我们只需要点一下就够了!咳咳,说回正题,主角zkCilent登场了

 

ZkClient是由Datameer的工程师开发的开源客户端,对Zookeeper的原生API进行了包装,实现了超时重连、Watcher反复注册等功能。

 

首先也是maven依赖

<!--引入zkclient-->

        <dependency>

            <groupId>com.github.sgroschupf</groupId>

            <artifactId>zkclient</artifactId>

            <version>0.1</version>

        </dependency>

 

写一个创建客户端的类

	public class ZkcilentUtil {
	    private static ZkClient zkClient;
	
	    public static ZkClient getZkClient(String host){
	        if (zkClient != null) {
	            return zkClient;
	        }
	        zkClient=new ZkClient(host,10000);
	        return zkClient;
	    }
	}
	
	之后就是把我们之前的操作使用zkClient来完成
	
	@Controller
	@RequestMapping("/zoo")
	public class ZooController {
	
	    ZkClient zkClient;
	    String path2 = "/test2222";
	
	    /** 创建节点*/
	    @RequestMapping("createZnode")
	    public String createZnodeZk() {
	        zkClient = ZkcilentUtil.getZkClient("127.0.0.1");
	//        zkClient.createEphemeral(path2,"111");//创建临时节点
	        zkClient.createPersistent(path2,"111");//创建永久节点
	        /** 设置子节点监听*/
	        zkClient.subscribeChildChanges(path2, new IZkChildListener() {
	            @Override
	            public void handleChildChange(String path, List<String> currentChrildren) throws Exception {
	                System.out.println("path = " + path);
	                System.out.println("currentChrildren = " + currentChrildren);
	            }
	        });
	        /** 设置数据监听*/
	        zkClient.subscribeDataChanges(path2, new IZkDataListener() {
	            @Override
	            public void handleDataChange(String path, Object data) throws Exception {
	                System.out.println("path = " + path+"改变了数据");
	                System.out.println("data = " + data);
	            }
	
	            @Override
	            public void handleDataDeleted(String path) throws Exception {
	                System.out.println("path = " + path+"删除了数据");
	            }
	        });
	        return "/index";
	    }
	
	    /** 获得子节点*/
	    @RequestMapping("getChrildrenZk")
	    public String getChrildrenZk(){
	        zkClient=ZkcilentUtil.getZkClient("127.0.0.1");
	        List<String> children = zkClient.getChildren(path);
	        System.out.println("children = " + children);
	        return "/index";
	    }
	
	    /** 获取节点数据*/
	    @RequestMapping("getDataZk")
	    public String getDataZk(){
	        zkClient = ZkcilentUtil.getZkClient("127.0.0.1");
	        String data = zkClient.readData(path2);
	        System.out.println("data = " + data);
	        return "/index";
	    }
	
	    /** 设置节点数据*/
	    @RequestMapping("setDataZk")
	    public String setDataZk(){
	        zkClient=ZkcilentUtil.getZkClient("127.0.0.1");
	        zkClient.writeData(path2,"222");
	        return "/index";
	    }
	}

完成!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值