• 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的数据同步与应答。

  • 相关阅读:
    C++标准模板(STL)- 类型支持 (运行时类型识别,type_info )
    UE4 回合游戏项目 22- 控制新角色
    gitlab-runner 的安装使用(含 .gitlab-ci.yml 的简单使用)
    485modbus转profinet网关在混料配料输送系统应用博图配置案例
    Apollo配置中心-手把手教你搭建Apollo配置中心运行环境
    A tour of gRPC:08 - gRPC 反射 与 Evans 客户端
    猿创征文|瑞吉外卖——管理端_(菜品)分类管理
    docker 安装 neo4j
    特征筛选还在用XGB的Feature Importance?试试Permutation Importance
    网页数据采集HTTP Get,Post登录提交数据--VBS之Microsoft.XMLHTTP对象
  • 原文地址:https://blog.csdn.net/qq_41708993/article/details/125433698