Zookeeper之原生连接、数据存储和事件机制

鉴于前面几篇博客已经将zookeeper单机和集群搭建完成,现在我们来了解下如何使用代码操作zookeeper

本文是建立连接和数据存储

直接开始干货:

首先pom文件引入zookeeper依赖,我装的版本是3.6.0 大家根据情况来定。

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

码来~~~~

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @Title: Spring-distributed
 * @Description:
 * @author: liaryank
 * @Date: 2020/5/6 11:28 上午
 * @Version: 1.0
 */
public class ZookeeperClient {

    public static void main(String[] args) {
        try  {
            
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            //这里绑定zookeeper服务器除了 observe 都要写上 因为可能出现任何一台机器成为leader 4000是心跳
            ZooKeeper zooKeeper = new ZooKeeper("192.168.3.32:2181," +
                    "192.168.3.33:2181,192.168.3.34:2181", 4000, new Watcher() {
                // watcher 的概念建议请看下面
                @Override
                public void process(WatchedEvent watchedEvent) {
                   if (Event.KeeperState.SyncConnected== watchedEvent.getState()){
                       //如果收到了服务端的响应事件,连接成功
                       countDownLatch.countDown();
                   }
                }
            });
            countDownLatch.await();
            System.out.println(zooKeeper.getState());

            //添加节点  ACL:ZooDefs.Ids.OPEN_ACL_UNSAFE权限控制 open是任何人都可以访问,PERSISTENT节点类型为持久化
            zooKeeper.create("/zk-persis-liaryank","0".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            Thread.sleep(1000);
            Stat stat=new Stat();
            //得到当前节点的值 stat是当前节点的值 也就是自己创建的/zk-persis-liaryank的值
            byte[] bytes=zooKeeper.getData("/zk-persis-liaryank",null,stat);
                    System.out.println(new String(bytes));
            //修改节点值 Version这里是属于乐观锁 
            zooKeeper.setData("/zk-persis-liaryank","1".getBytes(),stat.getVersion());
                    //得到当前节点的值
            byte[] bytes1=zooKeeper.getData("/zk-persis-liaryank",null,stat);
                    System.out.println(new String(bytes1));
            //zooKeeper.delete("/zk-persis-liaryank",stat.getVersion());
            zooKeeper.close();
            if (zooKeeper != null) {
                System.out.println("关闭连接");
                zooKeeper.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException | KeeperException e) {
            e.printStackTrace();
        }

    }
}

运行结果

服务器端查看  stat就是下面图中的数据,都可以获取到,可以自行打印输出下

已经将0 改为了1

 

再试试删除

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @Title: Spring-distributed
 * @Description:
 * @author: liaryank
 * @Date: 2020/5/6 11:28 上午
 * @Version: 1.0
 */
public class ZookeeperClient {

    public static void main(String[] args) {
        try  {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            ZooKeeper zooKeeper = new ZooKeeper("192.168.3.32:2181," +
                    "192.168.3.33:2181,192.168.3.34:2181", 4000, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                   if (Event.KeeperState.SyncConnected== watchedEvent.getState()){
                       //如果收到了服务端的响应事件,连接成功
                       countDownLatch.countDown();
                   }
                }
            });
            countDownLatch.await();
            System.out.println(zooKeeper.getState());
            Stat stat=new Stat();
            //得到当前节点的值
            byte[] bytes=zooKeeper.getData("/zk-persis-liaryank",null,stat);
            zooKeeper.delete("/zk-persis-liaryank",stat.getVersion());
            zooKeeper.close();
            if (zooKeeper != null) {
                System.out.println("关闭连接");
                zooKeeper.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException | KeeperException e) {
            e.printStackTrace();
        }

    }

运行结果

 

你可以将删除直接写到上边一起执行一下 加点打印输出就可以看到完整的增删改查效果了。

ok现在我们来讲事件机制

讲事件机制前先补充一下watcher

Watcher 监听机制是 Zookeeper 中非常重要的特性,我们 基于 zookeeper 上创建的节点,可以对这些节点绑定监听 事件,比如可以监听节点数据变更、节点删除、子节点状 态变更等事件,通过这个事件机制,可以基于 zookeeper 实现分布式锁、集群管理等功能.

watcher 特性:当数据发生变化的时候, zookeeper 会产 生一个 watcher 事件,并且会发送到客户端。但是客户端 只会收到一次通知。如果后续这个节点再次发生变化,那 么之前设置 watcher 的客户端不会再次收到消息。 (watcher 是一次性的操作)。 可以通过循环监听去达到 永久监听效果.

注册事件机制:  通过这三个操作来绑定事件 :getData、Exists、getChildren

触发事件: 凡是事务类型的操作,都会触发监听事件。 create /delete /setData

watcher 事件类型

None (-1),   客户端链接状态发生变化的时候,会收到 none 的事件

NodeCreated (1), 创建节点的事件。 比如zk-persis-liaryank时

NodeDeleted (2), 删除节点事件。
NodeDataChanged (3), 节点数据发生变更时。

NodeChildrenChanged (4); 子节点被创建、被删除、会 发生事件触发

码来~~~

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

/**
 * @Title: Spring-distributed
 * @Description:
 * @author: liaryank
 * @Date: 2020/5/6 3:19 下午
 * @Version: 1.0
 */
public class WatcherDemo {

    public static void main(String[] args) {
        try  {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            ZooKeeper zooKeeper = new ZooKeeper("192.168.3.32:2181," +
                    "192.168.3.33:2181,192.168.3.34:2181", 4000, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    System.out.println("全局默认事件:"+watchedEvent.getType());
                    if (Event.KeeperState.SyncConnected== watchedEvent.getState()){
                        //如果收到了服务端的响应事件,连接成功
                        countDownLatch.countDown();
                    }
                }
            });
            countDownLatch.await();
            System.out.println(zooKeeper.getState());

            zooKeeper.create("/zk-persis-liaryank","1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
            //这里通过exits绑定事件
            Stat stat = zooKeeper.exists("/zk-persis-liaryank", new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    System.out.println(watchedEvent.getType()+"==>"+watchedEvent.getPath());
                    try {
                        //再一次绑定事件,相当于永久注册监听 这里设置的true 是全局的watch
                        zooKeeper.exists(watchedEvent.getPath(),true);
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            //修改事务类型的操作来出发监听事件
            stat=zooKeeper.setData("/zk-persis-liaryank","2".getBytes(),stat.getVersion());
            Thread.sleep(1000);
            //然后删除
            zooKeeper.delete("/zk-persis-liaryank",stat.getVersion());
            //修改的时候让该内容进入只读状态
            System.in.read();
            zooKeeper.close();
            if (zooKeeper != null) {
                System.out.println("关闭连接");
                zooKeeper.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException | KeeperException e) {
            e.printStackTrace();
        }

    }
}

 运行结果如下

ok 原生操作到这里就完事了

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值