• zookeeper入门到精通07——zookeeper客户端API节点操作与原理


    前 言
    🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端
    ☕专栏简介:深入、全面、系统的介绍微服务常用技术栈zookeeper知识
    🌰 文章简介:本文将深入、全面介绍使用zookeeper的客户端API远程操作zookeeper服务器节点监听与存在与否的判断,并介绍写数据原理,建议收藏备用,创作不易,敬请三连哦
    🥒文章推荐:
    zookeeper入门到精通01——zookeeper入门
    zookeeper入门到精通02——zookeeper的本地安装操作
    zookeeper入门到精通03——zookeeper集群搭建
    zookeeper入门到精通04——zookeeper集群选举与集群操作
    Zookeeper入门到精通05——Zookeeper客户端命令行操作
    zookeeper入门到精通06——zookeeper客户端API创建节点

    一、监听节点

    先看看怎么获取子节点,启动zookeeper服务集群。编写并运行如下测试案例。

    public class ZKClient {
        ZooKeeper client;
    
        @Before
        public void init() throws IOException {
            // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
            String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
    //        String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
            int sessionTimeout = 20000;
            client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
    
                }
            });
        }
    
        @Test
        public void grtChild() throws InterruptedException, KeeperException {
        // 参数true表示开启子节点的监听
            List<String> children = client.getChildren("/", true);
            for (String child: children) {
                System.out.println(child);
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    上面并不能实时监听节点的变化,即使我们在使用getChildren是开启了子节点的监听。这是因为两个原因:第一,程序执行完一次监听后就退出了。第二,监听器注册一次只能够监听一次(参考:Zookeeper入门到精通05——Zookeeper客户端命令行操作,小节:监听器原理)。如何才能够实时监听子节点,并且一有变化就输出呢?很简单,把上面的代码稍微修改下即可。

    public class ZKClient {
        ZooKeeper client;
    
        @Before
        public void init() throws IOException {
            // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
            String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
    //        String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
            int sessionTimeout = 20000;
            client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {
                    List<String> children = null;
                    try {
    					// 参数true表示开启子节点的监听
                        children = client.getChildren("/", true);
                    } catch (KeeperException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    for (String child: children) {
                        System.out.println(child);
                    }
                }
            });
        }
    }
    
     @Test
        public void grtChild() throws InterruptedException, KeeperException {
            List<String> children = client.getChildren("/", true);
            for (String child: children) {
                System.out.println(child);
            }
            // 延时阻塞,防止程序退出
            Thread.sleep(Long.MAX_VALUE);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    二、判断节点是否存在

    public class ZKClient {
        ZooKeeper client;
    
        @Before
        public void init() throws IOException {
            // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
            String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
    //        String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
            int sessionTimeout = 20000;
            client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                @Override
                public void process(WatchedEvent watchedEvent) {}
            });
        }
        
       @Test
        public void exist() throws InterruptedException, KeeperException {
            Stat exists = client.exists("/sanguo1", false);
            System.out.println(exists==null?"not exist" : "exist");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    三、zookeeper的写数据原理

    不管是采用命令行还是api操作zookeeper集群,其实都是对于zookeeper进行写数据操作,那它的底层原理是什么呢?

    (1)直接向leader发写请求
    在这里插入图片描述
    如上图。假设zookeeper集群中有三台zookeeper服务器,首先client会给leader写数据,然后leader给其中一个follower写数据,之后follower会回复leader。此时,集群已经有半数服务器更新了数据,会由leader向client回复。之后leader继续与其它的follow进行数据同步与回复确认。

    (2)向follower发写请求
    在这里插入图片描述
    如上图。client给follower发送写请求后,follower会将请求转发给leader,leader进行写操作,并且选择一台follower完成写操作,follower响应请求并回复。当超过半数的服务器完成写操作后,会由leader回复给最开始响应client的follower,并由它对client进行回复。之后继续完成其它follower的数据同步与应答。

  • 相关阅读:
    SVN使用总结
    YZ系列工具:YZ11:VBA_窗体缩放
    8路高速光栅尺磁栅尺编码器4倍频计数转Modbus TCP网络模块 YL99-RJ45
    Java 8实战(八)- 数值流与构建流
    渗透工具——kali中wpscan简介
    基于FPGA的视频接口之千兆网口(四配置)
    前端开发者的创新工具:WebAssembly的崭露头角
    xposed hook的用法,原理是什么,做个比喻你就懂了
    LVS的简单介绍
    云端生成式 AI – 基于 Amazon EKS 的 Stable Diffusion 图像生成方案
  • 原文地址:https://blog.csdn.net/qq_41708993/article/details/125433698