当前位置:   article > 正文

Linux系统上安装zookeeper及三种zookeeper客户端的使用_zk客户端linux工具

zk客户端linux工具

主要说的内容有以下几点:

1、在linux上安装zookeepr

2、基本的操作命令

3、java中zookeeper三种客户端基本编写


1、在linux上安装zookeeper

       1、下载zookeeper安装包,下载地址

                链接:  https://pan.baidu.com/s/1r2co40V3PJGPZV4cOxC6rQ 

                密码:v4pa

        2、安装目录,一般我会将所有的软件安装在/usr/local/soft中,使用 cd /usr/local/soft 该命令找到需要下载的目录,将zookeeper安装包上传到该目录下。

cd /usr/local/soft

        3、使用该命令安装到当前目录下。

tar -zxvf apache-zookeeper-3.5.5-bin.tar.gz -C ./ 

         4、进入zookeeper文件夹,找到conf文件夹,将里面的 zoo_sample.cfg文件复制一份,将名字改为zoo.cfg。该文件就是zookeeper的配置文件。

  1. //打开配置文件目录
  2. cd apache-zookeeper-3.5.5-bin/conf/
  3. //将配置文件复制一份,并改名为zoo.cfg
  4. cp zoo_sample.cfg zoo.cfg

        5、修改完成后,进入到bin目录,启动zookeeper。

  1. //进入zookeeper的命令目录
  2. cd ..
  3. cd bin/
  4. //启动zookeeper
  5. ./zkServer.sh start
  6. //关闭zookeeper
  7. ./zkServer.sh stop
  8. //查看zookeeper状态
  9. ./zkServer.sh status

至此zookeeper安装完成。

2、基本操作命令

        zookeeper是一种类似于操作系统的文件系统数据结构,每个节点被称为znode,这个znode是可以存储数据的。

节点分为两大种,一种是持久化节点,一种是临时节点;

持久化节点又分为顺序持久化节点和持久化节点;

临时节点也分为顺序临时节点和临时节点。

当连接断掉后,所有的临时节点全部失效被删除;持久化节点则不会发生变化。

永久节点又分为顺序节点

        1、安装好zookeeper后,可以使用命令进行查看是否启动成功。

  1. //查看zookeeper是否启动
  2. ps -ef | grep zookeeper

        2、在bean目录下连接zookeeper

  1. //打开zookeeper连接命令
  2. ./zkCli.sh

        

        创建节点

  1. //创建节点 -e(创建临时节点,不加则创建永久节点) /xaioabi(节点名) 测试创建节点 (节点存放的目录)
  2. create -e /xiaobai 测试创建节点
  3. create -e /xiaobai/test01 123456

需要注意的一点是,节点只能一级一级创建,不能直接创建多级节点

  1. //查看根目录节点
  2. ls /
  3. //查看xiaobai子节点
  4. ls /xiaobai
  5. //退出会话
  6. //关闭当前会话
  7. close
  8. //关闭当前连接
  9. quit
  10. //修改节点数据
  11. //修改test01节点数据
  12. set /xiaoabi/test01 13579
  13. //查看节点数据
  14. get /xiaobai/test01
  15. // 删除节点
  16. //删除节点(只能删除没有子节点的节点,如果有的话,要先删除子节点才能删除该节点)
  17. delete /xiaobai/test01
  18. //删除根目录下所有没有子节点的节点
  19. deleteall /

需要注意的是:

        删除的节点有子节点,

        如果子节点数据为空,使用deleteall可以进行删除;

        如果子节点有数据,则会删除失败

3、java中zookeeper的三种客户端使用

java中使用zookeeper客户端有三种方式:

1、zookeeper:zookeeper提供的是原生java客户端

2、zkClient:在原生zookeeper基础上进行扩展的第三方java客户端

3、curator:Netflix公司在原生zookeeper基础上开源的java客户端

        1、zookeeper原生客户端

                zookeeper原生客户端是官方提供的,此客户端所有的东西都需要自己手写,包括创建连接,手写增删改查语句。由于此客户端属于纯原生,所有东西都必须自己写,所以一般不会使用该客户端进行开发。

        该客户端的弊端有一下几种:

                1、会话的连接是异步的。如果创建连接,只有等监听连接成功后才可以进行操作;

                2、Zookeeper的Watcher是一次性的,每次触发之后都需要重新进行注册;

                3、Session超时之后没有重连机制;

                4、异常处理繁琐,zookeeper提供了很多的异常。对于开发人员来说可能对这些异常都不知道如何处理;

                5、只提供了简单的byte[]接口,没有提供对象级别的序列化;

                6、开发的复杂性。创建节点前需要判断该节点是否存在;多级删除节点不支持,只能一级一级进行删除等等;

        需要添加的依赖:

  1. <dependencies>
  2. <!--zookeeper的官方客户端jar包依赖-->
  3. <dependency>
  4. <groupId>org.apache.zookeeper</groupId>
  5. <artifactId>zookeeper</artifactId>
  6. <version>3.5.5</version>
  7. </dependency>
  8. </dependencies>

编写测试代码: 

  1. package com.bpc.client;
  2. import org.apache.zookeeper.*;
  3. import org.apache.zookeeper.data.Stat;
  4. import java.io.IOException;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. import java.util.concurrent.CountDownLatch;
  8. /**
  9. * @author xiaobai
  10. */
  11. public class ZookeeperClientTest01 {
  12. private static final String ZK_ADDRESS = "127.0.0.1:2181";
  13. private ZooKeeper zooKeeper;
  14. private Integer sessionTimeout;
  15. /**
  16. * 删除节点
  17. */
  18. public void deletePath(String path) throws KeeperException, InterruptedException {
  19. //判断该节点下面是否有子节点,有子节点删除子节点
  20. List<String> childrenPathList = getChildrenPath(path);
  21. if (!childrenPathList.isEmpty()) {
  22. //删除子节点
  23. for (String childrenPath : childrenPathList) {
  24. //迭代删除子节点
  25. deletePath(path + "/" + childrenPath);
  26. }
  27. }
  28. zooKeeper.delete(path, -1);
  29. System.out.println("删除节点:" + path + "成功!");
  30. return;
  31. }
  32. /**
  33. * 获取所有子节点名称
  34. */
  35. public List<String> getChildrenPath(String path) throws KeeperException, InterruptedException {
  36. //判断该节点是否有子节点
  37. int numChildren = getNumChildren(path);
  38. if (0 == numChildren) {
  39. return new ArrayList<>();
  40. }
  41. return zooKeeper.getChildren(path, false);
  42. }
  43. /**
  44. * 修改节点内容
  45. */
  46. public void setContent(String path, String content) throws KeeperException, InterruptedException {
  47. //节点名称、修改内容,版本号(-1表示所有版本号都匹配)
  48. zooKeeper.setData(path, content.getBytes(), -1);
  49. }
  50. /**
  51. * 获取节点子节点数量
  52. */
  53. public int getNumChildren(String path) throws KeeperException, InterruptedException {
  54. //存放节点状态信息
  55. Stat stat = isExist(path);
  56. return stat == null ? 0 : stat.getNumChildren();
  57. }
  58. /**
  59. * 获取节点内容
  60. */
  61. public String getPath(String path) throws KeeperException, InterruptedException {
  62. //存放节点状态信息
  63. Stat stat = new Stat();
  64. byte[] data = zooKeeper.getData(path, false, stat);
  65. return new String(data);
  66. }
  67. /**
  68. * 检查节点是否存在
  69. */
  70. public Stat isExist(String path) throws KeeperException, InterruptedException {
  71. //节点名称、是否观察
  72. Stat stat = zooKeeper.exists(path, false);
  73. return stat;
  74. }
  75. /**
  76. * 创建节点
  77. */
  78. public String createNode(String path, String content) throws KeeperException, InterruptedException {
  79. //节点名称;节点存储内存数据;权限;节点状态(持久性节点)
  80. String pathNode = zooKeeper.create(path, content.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
  81. System.out.println("创建节点的结果:" + pathNode);
  82. return pathNode;
  83. }
  84. /**
  85. * 关闭会话连接
  86. */
  87. public void close() throws InterruptedException {
  88. zooKeeper.close();
  89. }
  90. /**
  91. * 获取连接
  92. */
  93. public ZooKeeper getConnect(int sessionTimeout) throws IOException, InterruptedException {
  94. //倒计数器,倒数1个
  95. CountDownLatch countDownLatch = new CountDownLatch(1);
  96. //创建zooKeeper对象
  97. //参数:连接地址和端口;会话超时时间(该连接保持时间);观察者对象(用来观察连接过程)
  98. ZooKeeper zooKeeper = new ZooKeeper(ZK_ADDRESS, sessionTimeout, (WatchedEvent event) -> {
  99. //判断状态是否是已连接
  100. if (Watcher.Event.KeeperState.SyncConnected.equals(event.getState())) {
  101. System.out.println("连接成功。。。。");
  102. //zookeeper连上了
  103. countDownLatch.countDown();
  104. }
  105. });
  106. //连接成功后返回zookeeper对象
  107. countDownLatch.await();
  108. return zooKeeper;
  109. }
  110. public ZookeeperClientTest01(Integer sessionTimeout) throws IOException, InterruptedException {
  111. this.sessionTimeout = sessionTimeout;
  112. this.zooKeeper = getConnect(sessionTimeout);
  113. }
  114. public ZooKeeper getZooKeeper() { return zooKeeper; }
  115. public void setZooKeeper(ZooKeeper zooKeeper) { this.zooKeeper = zooKeeper;}
  116. public Integer getSessionTimeout() { return sessionTimeout; }
  117. public void setSessionTimeout(Integer sessionTimeout) {this.sessionTimeout = sessionTimeout;}
  118. }

测试一下:

  1. public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
  2. //节点名称
  3. String path = "/test02";
  4. //创建对象并获取连接
  5. ZookeeperClientTest01 test01 = new ZookeeperClientTest01(5000);
  6. //检查节点是否存在
  7. Stat isExist = test01.isExist(path);
  8. if (null == isExist) {
  9. //创建节点
  10. test01.createNode(path, "创建节点内容");
  11. //创建子节点
  12. test01.createNode(path+"/test02","创建子节点001");
  13. }
  14. //获取节点
  15. String pathContent = test01.getPath(path);
  16. System.out.println("节点存放的内容:" + pathContent);
  17. //修改节点内容
  18. test01.setContent(path, "修改节点内容");
  19. //获取该节点下的所有子节点
  20. List<String> childrenPathList = test01.getChildrenPath(path);
  21. for (String childrenPath : childrenPathList) {
  22. System.out.println("子节点名称:" + childrenPath);
  23. }
  24. //删除节点
  25. test01.deletePath(path);
  26. //关闭会话
  27. test01.close();
  28. }

       

2、zkClient客户端

        zkClient客户端是在原生zookeeper客户端上进行扩展的第三方开源客户端。该客户端在前几年被经常使用。

        该客户端的优点:

        1、提供了对象序列化的方式;

        2、添加了session超时重试机制;

        3、Wacther实现了反复注册;

        4、对crud(增删改查)进行了封装处理;例如:提供了迭代删除接口等等;

        该客户端的弊端:

                1、几乎没有参考文档;

                2、session超时重试机制比较难用

                3、没有提供各种场景的实现

        需要导入的依赖:

  1. <!-- zkclient 客户端-->
  2. <dependency>
  3. <groupId>com.101tec</groupId>
  4. <artifactId>zkclient</artifactId>
  5. <version>0.11</version>
  6. </dependency>

编写测试代码:

  1. package com.bpc.client;
  2. import org.I0Itec.zkclient.ZkClient;
  3. import java.util.List;
  4. /**
  5. * @author xiaobai
  6. */
  7. public class Test02 {
  8. public static void main(String[] args) {
  9. String ZK_ADDRESS = "127.0.0.1:2181";
  10. String path = "/test04";
  11. //创建连接
  12. ZkClient zkClient = new ZkClient(ZK_ADDRESS);
  13. //检查节点是否存在(节点名称)
  14. boolean isExist = zkClient.exists(path);
  15. //节点不存在则添加
  16. if (!isExist) {
  17. //创建节点(节点名称、节点内容)
  18. zkClient.createPersistent(path, "创建节点test004");
  19. //创建子节点(节点名称、节点内容)
  20. zkClient.createPersistent(path + "/znode01", "创建子节点znode01");
  21. }
  22. //获取节点数据(节点名称)
  23. String content = zkClient.readData(path);
  24. System.out.println("节点存储的数据:" + content);
  25. //修改节点内容(节点名称、节点内容)
  26. zkClient.writeData(path, "修改节点内容成功!");
  27. //获取所以子节点(节点名称)
  28. List<String> childrenList = zkClient.getChildren(path);
  29. for (String children : childrenList) {
  30. System.out.println("获取子节点名称:" + children);
  31. }
  32. //删除单节点删除(节点名称)
  33. boolean delete = zkClient.delete(path + "/znode01");
  34. System.out.println("删除单节点是否成功:" + delete);
  35. //递归删除多级节点(节点名称)
  36. boolean deleteAll = zkClient.deleteRecursive(path);
  37. System.out.println("删除多级节点是否成功:" + deleteAll);
  38. }
  39. }

        3、curator客户端

                curator客户端是目前官方推荐的,不管是从性能还是封装来说是目前比较好的框架。该框架是Netflix公司开发的开源框架,捐献给Apache后,成为Apache开源框架。相比于zookeeper客户端,进行了高度的封装和抽象,解决了非常底层的细节开发工作,包括超时重连机制、反复注册Watcher、NodeExistsException异常等等。并且提供了一套可读性和易用性的Fluent风格的API接口。

curator客户端的优点:

        1、提供了一套Fluent风格的API接口,大大提高了可读性和易用性;

        2、解决Watcher注册一次就会失效的问题,实现了Wacther反复注册;

        3、提供了不同场景的抽象封装,例如:共享锁服务、Master选举机制和分布式计算器等场景;

        4、更加倾向于开发人员,例如:链式调用风格、分布式锁、zookeeper工具类等等;

        5、该框架为我们封装了很多逻辑和方法,使得框架的容错性大大提供。使得我们开发人员更专注于业务。

需要导入的依赖:

  1. <!-- curator-framework -->
  2. <dependency>
  3. <groupId>org.apache.curator</groupId>
  4. <artifactId>curator-framework</artifactId>
  5. <version>4.2.0</version>
  6. </dependency>
  7. <!-- curator-recipes -->
  8. <dependency>
  9. <groupId>org.apache.curator</groupId>
  10. <artifactId>curator-recipes</artifactId>
  11. <version>4.2.0</version>
  12. </dependency>

编写测试代码:

  1. public static void main(String[] args) throws Exception {
  2. String path = "/test05";
  3. CuratorTest03 curator = new CuratorTest03();
  4. //检查节点是否存在
  5. Stat stat = curator.client.checkExists().forPath(path);
  6. if (null == stat) {
  7. //创建节点
  8. curator.client.create()
  9. .creatingParentsIfNeeded()
  10. .withMode(CreateMode.PERSISTENT)
  11. .forPath(path, "创建节点test05".getBytes());
  12. //创建子节点
  13. curator.client.create()
  14. .creatingParentsIfNeeded()
  15. .withMode(CreateMode.PERSISTENT)
  16. .forPath(path + "/test01", "创建子节点test01".getBytes());
  17. curator.client.create()
  18. .creatingParentsIfNeeded()
  19. .withMode(CreateMode.PERSISTENT)
  20. .forPath(path + "/test02", "创建子节点test02".getBytes());
  21. }
  22. //修改节点数据
  23. curator.client.setData().forPath(path, "修改主节点数据内容".getBytes());
  24. //获取节点数据
  25. String node = new String(curator.client.getData().forPath(path));
  26. String test01Node = new String(curator.client.getData().forPath(path + "/test01"));
  27. System.out.println("主节点数据:" + node);
  28. System.out.println("子节点Test01数据:" + test01Node);
  29. //获取所有子节点
  30. List<String> childrenList = curator.client.getChildren().forPath(path);
  31. for (String children : childrenList) {
  32. System.out.println("子节点名称:" + children);
  33. }
  34. //单个节点删除
  35. curator.client.delete().forPath(path + "/test02");
  36. //迭代删除节点
  37. curator.client.delete().deletingChildrenIfNeeded().forPath(path);
  38. //查看节点是否存在
  39. Stat stat1 = curator.client.checkExists().forPath(path);
  40. if (null == stat1) {
  41. System.out.println(path + "节点不存在");
  42. } else {
  43. System.out.println(path + "该节点存在");
  44. }
  45. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号