阅读 140

Zookeeper单机部署、必备命令、场景实战

前言

昨天花哥在第一篇文章中介绍了Zookeeper是什么,大家对它应该也有了一个初步的概念,今天呢,我们就实际操作一波,看它是如何部署到我们的机器上,在代码中又是如何应用的。

单机版安装(windows)

  1. 打开Zookeeper官网 首页,点击Download,就可以跳转到下载页,根据需要选择对应的版本。

image-20211102094012711.png

  1. 如果官网访问失败,花哥也将【3.6.3】、【3.7.0】两个版本上传到百度网盘,有需要的小伙伴可以直接下载

链接:pan.baidu.com/s/19wHXUKTf… 提取码:chwm

  1. 将压缩包解压,打开conf目录,将zoo_sample.cfg拷贝一份并命名为zoo.cfg

image.png

  1. 上述配置完毕后,打开bin目录,双击zkServer.cmd启动服务端

  2. 服务启动完成,双击zkCli.cmd即可以进行测试

注意:zookeeper依赖java环境,因此在安装前,保证操作系统中java环境正常。

单机版安装(linux)

  1. 下载解压

# cd /usr/local # wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.0/apache-zookeeper-3.7.0-bin.tar.gz # tar -zxvf apache-zookeeper-3.7.0-bin.tar.gz # cd apache-zookeeper-3.7.0-bin 复制代码

  1. 修改配置

# cp conf/zoo_sample.cfg conf/zoo.cfg 复制代码

  1. 启动服务

# bin/zkServer.sh start 复制代码

  1. 启动客户端

# bin/zkCli.sh 复制代码

注意:如果wget无法使用,可以使用yum -y install wget先将其安装,或者直接将zookeeper包下载到本地,然后上传至服务器。

配置文件说明

在单机版中,我们只需要配置以下三个参数就可以正常启动

#心跳时间,单位毫秒 tickTime = 2000 #数据存放目录 dataDir = /usr/local/zookeeper #客户端连接端口 clientPort = 2181 复制代码

当然,在实际应用中,上面三个参数可能是不够的,这时我们可以在官网指南中查看每一个配置项的作用,根据实际需求选择。 \

image.png

命令使用说明

  • 使用ls可以查看zookeeper当前包含的节点

image.png

  • 使用create创建一个新的子节点

image.png

  • 使用ls再来看下根目录下包含的子节点,testData已经被创建

image.png

  • 使用get查看节点内容

image.png

  • 使用set设置节点内容

image.png

  • 使用delete删除节点

image.png

常用命令介绍

  • 客户端命令

命令说明示例
ls获取节点ls /
create创建子节点create /testData 100
delete删除节点delete /testData
get从指定节点读取数据get -s /testData
set设置数据到指定节点set /testData 200help
help查看帮助
quit退出客户端
  • 服务命令

命令说明
sh bin/zkServer.sh start启动zk服务
sh bin/zkServer.sh stop停止zk服务
sh bin/zkServer.sh restart重启zk服务
sh bin/zkServer.sh status查看服务状态

代码测试

package com.basic.business.demo;  import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.Watcher.Event.KeeperState; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat;  /**  * zk测试demo  *  */ public class ZookeeperDemo implements Watcher {      private static ZooKeeper zk = null;     private static Stat stat = new Stat();      public static void main(String[] args) throws Exception {         //被监听的节点         String path = "/testData";         //连接zookeeper并注册监听器         zk = new ZooKeeper("127.0.0.1:2181", 5000, new ZookeeperDemo());         //注册监听器,监听节点/testData值的变化         zk.getData(path,true,stat);         Thread.sleep(Integer.MAX_VALUE);     }      public void process(WatchedEvent event) {         //zk连接成功事件         if (KeeperState.SyncConnected == event.getState()) {             //zk节点数据变化时通知事件             if (event.getType() == EventType.NodeDataChanged) {                 try {                     System.out.println("修改后的值:" + new String(zk.getData(event.getPath(), true, stat)));                 } catch (Exception e) {                 }             }         }     } } 复制代码

然后连接zk客户端,修改子节点/testData的内容,就能观察到idea控制台能够打印出修改后的内容。

执行结果8.gif

官网实例

有兴趣的小伙伴,可以跟着官网的示例走一下,共计有两个类,代码贴出来,花哥就不再演示了。地址:zookeeper.apache.org/doc/current…

//Executor.java /**  * A simple example program to use DataMonitor to start and  * stop executables based on a znode. The program watches the  * specified znode and saves the data that corresponds to the  * znode in the filesystem. It also starts the specified program  * with the specified arguments when the znode exists and kills  * the program if the znode goes away.  */ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; public class Executor     implements Watcher, Runnable, DataMonitor.DataMonitorListener {     String znode;     DataMonitor dm;     ZooKeeper zk;     String filename;     String exec[];     Process child;     public Executor(String hostPort, String znode, String filename,             String exec[]) throws KeeperException, IOException {         this.filename = filename;         this.exec = exec;         zk = new ZooKeeper(hostPort, 3000, this);         dm = new DataMonitor(zk, znode, null, this);     }     /**      * @param args      */     public static void main(String[] args) {         if (args.length < 4) {             System.err                     .println("USAGE: Executor hostPort znode filename program [args ...]");             System.exit(2);         }         String hostPort = args[0];         String znode = args[1];         String filename = args[2];         String exec[] = new String[args.length - 3];         System.arraycopy(args, 3, exec, 0, exec.length);         try {             new Executor(hostPort, znode, filename, exec).run();         } catch (Exception e) {             e.printStackTrace();         }     }     /***************************************************************************      * We do process any events ourselves, we just need to forward them on.      *      * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.proto.WatcherEvent)      */     public void process(WatchedEvent event) {         dm.process(event);     }     public void run() {         try {             synchronized (this) {                 while (!dm.dead) {                     wait();                 }             }         } catch (InterruptedException e) {         }     }     public void closing(int rc) {         synchronized (this) {             notifyAll();         }     }     static class StreamWriter extends Thread {         OutputStream os;         InputStream is;         StreamWriter(InputStream is, OutputStream os) {             this.is = is;             this.os = os;             start();         }         public void run() {             byte b[] = new byte[80];             int rc;             try {                 while ((rc = is.read(b)) > 0) {                     os.write(b, 0, rc);                 }             } catch (IOException e) {             }         }     }     public void exists(byte[] data) {         if (data == null) {             if (child != null) {                 System.out.println("Killing process");                 child.destroy();                 try {                     child.waitFor();                 } catch (InterruptedException e) {                 }             }             child = null;         } else {             if (child != null) {                 System.out.println("Stopping child");                 child.destroy();                 try {                     child.waitFor();                 } catch (InterruptedException e) {                     e.printStackTrace();                 }             }             try {                 FileOutputStream fos = new FileOutputStream(filename);                 fos.write(data);                 fos.close();             } catch (IOException e) {                 e.printStackTrace();             }             try {                 System.out.println("Starting child");                 child = Runtime.getRuntime().exec(exec);                 new StreamWriter(child.getInputStream(), System.out);                 new StreamWriter(child.getErrorStream(), System.err);             } catch (IOException e) {                 e.printStackTrace();             }         }     } } 复制代码

//DataMonitor.java /**  * A simple class that monitors the data and existence of a ZooKeeper  * node. It uses asynchronous ZooKeeper APIs.  */ import java.util.Arrays; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.AsyncCallback.StatCallback; import org.apache.zookeeper.KeeperException.Code; import org.apache.zookeeper.data.Stat; public class DataMonitor implements Watcher, StatCallback {     ZooKeeper zk;     String znode;     Watcher chainedWatcher;     boolean dead;     DataMonitorListener listener;     byte prevData[];     public DataMonitor(ZooKeeper zk, String znode, Watcher chainedWatcher,             DataMonitorListener listener) {         this.zk = zk;         this.znode = znode;         this.chainedWatcher = chainedWatcher;         this.listener = listener;         // Get things started by checking if the node exists. We are going         // to be completely event driven         zk.exists(znode, true, this, null);     }     /**      * Other classes use the DataMonitor by implementing this method      */     public interface DataMonitorListener {         /**          * The existence status of the node has changed.          */         void exists(byte data[]);         /**          * The ZooKeeper session is no longer valid.          *          * @param rc          *                the ZooKeeper reason code          */         void closing(int rc);     }     public void process(WatchedEvent event) {         String path = event.getPath();         if (event.getType() == Event.EventType.None) {             // We are are being told that the state of the             // connection has changed             switch (event.getState()) {             case SyncConnected:                 // In this particular example we don't need to do anything                 // here - watches are automatically re-registered with                 // server and any watches triggered while the client was                 // disconnected will be delivered (in order of course)                 break;             case Expired:                 // It's all over                 dead = true;                 listener.closing(KeeperException.Code.SessionExpired);                 break;             }         } else {             if (path != null && path.equals(znode)) {                 // Something has changed on the node, let's find out                 zk.exists(znode, true, this, null);             }         }         if (chainedWatcher != null) {             chainedWatcher.process(event);         }     }     public void processResult(int rc, String path, Object ctx, Stat stat) {         boolean exists;         switch (rc) {         case Code.Ok:             exists = true;             break;         case Code.NoNode:             exists = false;             break;         case Code.SessionExpired:         case Code.NoAuth:             dead = true;             listener.closing(rc);             return;         default:             // Retry errors             zk.exists(znode, true, this, null);             return;         }         byte b[] = null;         if (exists) {             try {                 b = zk.getData(znode, false, null);             } catch (KeeperException e) {                 // We don't need to worry about recovering now. The watch                 // callbacks will kick off any exception handling                 e.printStackTrace();             } catch (InterruptedException e) {                 return;             }         }         if ((b == null && b != prevData)                 || (b != null && !Arrays.equals(prevData, b))) {             listener.exists(b);             prevData = b;         }     } } 复制代码

写在最后

今天介绍了zookeeper的单机部署和一些常用命令,已经在java中如何使用,下一章花哥对Zookeeper的核心内容进行讲解,如果觉得文章有一些不妥,小伙伴们可以大胆提出来,一起进步,共同学习。


作者:JavaGieGie
链接:https://juejin.cn/post/7025887917243383844


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐