Zookeeper--实战(开发重点)

    1. 分布式安装部署
      1. 集群规划
        1. 在centos-master,centos-slave1,centos-slave2三个节点上部署zookeeper  
      2. 解压安装
        • 解压安装zookeeper安装包到 /opt/目录下  tar -zxvf  zookeeper安装包
        • 将解压的目录同步到centos-slave1和centos-slave2:scp -r zookeeper-3.4.10 slave1:/opt/  ,scp -r zookeeper-3.4.10 slave2:/opt/
      3. 配置服务器编号  
        1. 在/opt/zookeeper-3.4.10/这个目录下创建zkData:mkdir -p zkData
        2. 在/opt/zookeeper-3.4.10/zkData目录下创建myid的文件 :touch myid
        3. 编辑myid文件:vim myid,在文件中添加与server对应的编号:1
        4. 拷贝配置好的zookeeper到其他机器上 :scp -r zkData slave1:/opt/zookeeper-3.4.10/
        5. 并分别修改centos-slave1和centos-slave2上的myid文件内容为2 和3
      4. 配置zoo.cfg文件
        1. 复制/opt/module/zookeeper-3.4.10/conf这个目录下的z00 sample.cfg 为zo0.cfgv
           cp zoo_sample.cfg  zoo.cfg.

        2. 打开zoo.cfg 文件。
           vim zoo.cfgv
          修改数据存储路径配置
          dataDir=/ opt/ module/ zookeeper-3.4.10/ zkDatar
          增加如下配置:
          #######################cluster##########################
          server.1=master:2888:3888
          server.2=slave1:2888:3888
          server.3=slave2:2888:3888

        3. 同步zoo.cfg配置文件。
          scp -r zoo.cfg slave1:/opt/zookeeper-3.4.10/conf/ ,scp -r zoo.cfg slave2:/opt/zookeeper-3.4.10/conf/ 

        4. 配置参数解读
          server .A=B:C:D. 4
          A是一个数字,表示这个是第几号服务器;。
          集群模式下配置一个文件myid,这个文件在dataDir.目录下,这个文件里面有一个数据
          就是A的值,Zookeeper 启动时读取此文件,拿到里面的数据与zo0.cfg.里面的配置信息比

          较从而判断到底是哪个server。
          B是这个服务器的ip地址;。
          C是这个服务器与集群中的Leader服务器交换信息的端口;。
          D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的
          Leader,而这个端口就是用来执行选举时服务器相互通信的端口。

        5.  集群的操作

          1. 分别启动Zookeeper

            • bin/zkServer.sh start

            • bin/zkServer.sh start

            • bin/zkServer.sh start

          2. 查看状态

            • bin/zkServer.sh status

            • bin/zkServer.sh status

            • bin/zkServer.sh status

          3.  

          4. 半数选举机制,如果有三台机器,第一台上线会先投自己一票,没有够半数上,则失败

          5. 等到第二台机器来的时候,第一台会投第二台一票(因为他投自己没成功,所以会投比自己序号大的),机器上线总是线投自己(自私的),第二台投自己一票,二票在半数以上,则成立,第二台机器时leader,后面来第三台,由于前面已将选出leader所有自动成为flower

    2. 客户端的命令操作

      1. 启动客户端 :  ./zkCli.sh

      2. 显示所有的操作命令
        1. 使用命令:help
      3. 查看当前znode中所以的内容  :命令:ls  /

      4. 查看当前节点的详细数据 :命令: ls2  /

      5. 分别创建两个普通的节点(创建的节点不能没有内容,否则创建节点不成共)
      6. 获取节点中的内容
        • 获取的节点不能在最后面加 / 这样节点内容获取不到,必须是 get  /节点名程)
      7. 创建短暂节点,客户端一但掉线重新连接,则短暂节点消失:命令:create -e /节点路径名/节点名  ‘节点内容’ 

      8. 创建带序号的节点
        • 先创建一个根节点:create /sanguo/weiguo ‘caocoa’
        • 在创建带序号的节点:create -s /snaguo/weiguo ‘caocao’
        • 如果有节点中有节点,则会按需还递增,如没有其他节点,则序号从0开始递增
        • 如果原来没有序号节点,序聘从0开始依次递增。如果原节点下已有2个节点,则再
          排序时从2开始,以此类推

        • 不能创建 create  /没有的节点/没有的节点  必须一次创建一层的一个,不能透过第一层创建第二层的节点 
      9. 修改节点的值:set /节点名称  ‘修改的值’ 

      10. 节点值的变化监听

        1. 在节点master 执行:get / 节点名  watch  只能对节点做一次监听,第二次改变就监听不到了

        2. 在节点slave1 修改上上节点的值,节点mater就会监听到,但只能监听一次

      11. 监听节点的子节点的变化(路径的变化)
        1. 在master设置节点的监听:ls /sanguo watch  ,监听子节点的变化
        2. 在slave1中  /sanguo 的节点增加一个节点,看看master的变化
        3. 同样master设置了一次监听,当 /sanguo第二次变化时,就不能监听到了
      12. 删除节点 :delete /节点名

      13. 递归删除节点  rmr /节点名

      14. 查看节点的状态: stat /节点名

    3. API应用
      1. Idea环境搭建
        1.  <dependencies>
              <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-core</artifactId>
                <version>2.8.2</version>
              </dependency>
              <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.10</version>
              </dependency>
              <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
              </dependency>
              <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.5.RELEASE</version>
              </dependency>
              <dependency>
                <groupId>org.junit.jupiter</groupId>
                <artifactId>junit-jupiter</artifactId>
                <version>RELEASE</version>
                <scope>compile</scope>
              </dependency>
              <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
              </dependency>
            </dependencies>

           

            
      2. 创建Zookeeper客户端
        1.  
             @Test
              public void init() throws IOException {
          
                  zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() {
                      @Override
                      public void process(WatchedEvent watchedEvent) {
          
                      }
                  });
                  System.out.println("这是一个测试类"+zkClient.toString());
              }

           

           
      3. 创建子节点
        1.   
          package com.model.test;
          
          import org.apache.zookeeper.*;
          import org.junit.Before;
          import org.junit.Test;
          
          import java.io.IOException;
          import java.nio.charset.StandardCharsets;
          
          public class Zookeeper001 {
              private String connectString="master:2181,slave1:2181,slave2:2181";
              private int sessionTimeout=20000;
              private ZooKeeper zkClient;
              @Before
              public void init() throws IOException {
          
                  zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() {
                      @Override
                      public void process(WatchedEvent watchedEvent) {
          
                      }
                  });
                  System.out.println("这是一个测试类"+zkClient.toString());
              }
              @Test
              public void createNode() throws KeeperException, InterruptedException {
          
                  String path = zkClient.create("/jia", "zs".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                  System.out.println(path);
              }
          }

           

        2.  

           

            
      4. 获取子节点并监听上数据
        1. package com.model.test;
          
          import org.apache.zookeeper.*;
          import org.junit.Before;
          import org.junit.Test;
          
          import java.io.IOException;
          import java.nio.charset.StandardCharsets;
          import java.util.List;
          
          public class Zookeeper001 {
              private String connectString="master:2181,slave1:2181,slave2:2181";
              private int sessionTimeout=20000;
              private ZooKeeper zkClient;
              @Before
              public void init() throws IOException {
          
                  zkClient = new ZooKeeper(connectString,sessionTimeout, new Watcher() {
                      @Override
                      public void process(WatchedEvent watchedEvent) {
                          //实时的监控某节点下的节点数量变化,这里演示根目录下节点数量变化
                          System.out.println("*********start***********");
                          try {
                              List<String> children = zkClient.getChildren("/", true);
                              for (String child:children) {
                                  System.out.println(child);
                              }
                              System.out.println("********end*********");
                          } catch (KeeperException e) {
                              e.printStackTrace();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
          
                      }
                  });
                  System.out.println("这是一个测试类"+zkClient.toString());
              }
              //创建节点
              @Test
              public void createNode() throws KeeperException, InterruptedException {
          
                  String path = zkClient.create("/jia", "zs".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
                  System.out.println(path);
              }
              @Test
              public void getChildWatch(){
                  List<String> children = null;
                  try {
                      children = zkClient.getChildren("/", true);
                      for (String child:children) {
                          System.out.println(child);
                      }
                  } catch (KeeperException e) {
                      e.printStackTrace();
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  try {
                      Thread.sleep(Long.MAX_VALUE);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }

           

        2.  

           

           

           
      5. 判断Znode是否存在
        1.  

           

            
    4. 监听服务器节点动态上下线案例 
      1.  client代码

        1. package com.model.DoTaiShangXiaXian;
          
          import org.apache.zookeeper.KeeperException;
          import org.apache.zookeeper.WatchedEvent;
          import org.apache.zookeeper.Watcher;
          import org.apache.zookeeper.ZooKeeper;
          
          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.List;
          
          public class Client {
          
              public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
          
                  Client client=new Client();
          //        1.连接zookeeper服务器
                  client.getConnect();
          //        2.注册监听
                  client.getChildren();
          //        3.业务逻辑处理
                  client.business();
              }
          
              private void business() throws InterruptedException {
                  Thread.sleep(Long.MAX_VALUE);
              }
          
              private void getChildren() throws KeeperException, InterruptedException {
                  List<String> children = zkClient.getChildren("/servers", true);
          //        创建存储服务器节点主机名称的集合
                  ArrayList<String> hosts=new ArrayList<>();
                  for (String c:children){
                      byte[] data = zkClient.getData("/servers/"+c, false, null);
                      hosts.add(new String(data));
                  }
          //        将所有的在线主机名称打印到控制台
                  System.out.println(hosts);
              }
          
              private final String connectString="master:2181,slave1:2181,slave2:2181";
              private int sessionTimeout=30000;
              private ZooKeeper zkClient;
              private void getConnect() throws IOException {
                  zkClient= new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                      @Override
                      public void process(WatchedEvent watchedEvent) {
                          try {
                              getChildren();
                          } catch (KeeperException e) {
                              e.printStackTrace();
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  });
              }
          }

           

            
      2. server代码

        1.   
          package com.model.DoTaiShangXiaXian;
          
          import org.apache.zookeeper.*;
          
          import java.io.IOException;
          
          public class Server {
              //实现服务器动态上下线
          
              //服务器端
          
              public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
                  Server service=new Server();
                  //  1.连接zookeeper服务器集群
                  service.getConnect();
          
          //    2.在zookeeper上注册节点
                  service.register(args[0]);
          
          //    3.业务逻辑处理
                  service.business();
              }
          
              private void business() throws InterruptedException {
                  Thread.sleep(Long.MAX_VALUE);
              }
          
              private void register(String hostname) throws KeeperException, InterruptedException {
                  String path = zkClient.create("/servers/server", hostname.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
                  System.out.println(hostname+"is online");
              }
          
              private final  String  connectString="master:2181,slave1:2181,slave2:2181";
              private  int sessionTimeout=30000;
              private ZooKeeper zkClient;
              public void getConnect() throws IOException {
          
                     zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
                      @Override
                      public void process(WatchedEvent watchedEvent) {
          
                      }
                  });
              }
          
          }

           

            
      3. 只运行client代码,在zookeeper集群操作节点变化,观察控制台

        1.  

           

        2. 同时运行server和client类观察控制台变化

        3.  

           

           

           

            

           

           

             

             
posted @ 2021-05-31 21:26  张紫韩  阅读(190)  评论(0编辑  收藏  举报