Java操作Zookeeper原理及过程详解

 更新时间:2020年05月19日 08:34:37   作者:玄同太子  
这篇文章主要介绍了Java操作Zookeeper原理及过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

ZooKeeper 是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。

Zookeeper 一个最常用的使用场景就是用于担任服务生产者和服务消费者的注册中心。 服务生产者将自己提供的服务注册到Zookeeper中心,服务的消费者在进行服务调用的时候先到Zookeeper中查找服务,获取到服务生产者的详细信息之后,再去调用服务生产者的内容与数据。如下图所示,在 Dubbo架构中 Zookeeper 就担任了注册中心这一角色。

maven依赖

<dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.6.0</version>
</dependency>

程序其它依赖:

<!-- Logger(log4j2) -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.11.2</version>
</dependency>
<!-- Log4j 1.x API Bridge -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-1.2-api</artifactId>
  <version>2.11.2</version>
</dependency>
<!-- SLF4J Bridge -->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.11.2</version>
</dependency>

<dependency>
  <groupId>org.apache.zookeeper</groupId>
  <artifactId>zookeeper</artifactId>
  <version>3.6.0</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
    </exclusion>
  </exclusions>
</dependency>

API操作代码:

package com.zhi.test;

import java.util.List;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.TestMethodOrder;

/**
 * Zookeeper操作测试
 * 
 * @author 张远志
 * @since 2020年5月3日14:31:28
 *
 */
@TestInstance(Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class ZookeeperTest {
  private final Logger logger = LogManager.getLogger(this.getClass());
  private ZooKeeper zooKeeper;
  private final String path = "/test";

  @BeforeAll
  public void init() throws Exception {
    zooKeeper = new ZooKeeper("192.168.59.131:2181", 60000, new Watcher() {
      public void process(WatchedEvent event) {
        logger.info("事件类型:{},路径:{}", event.getType(), event.getPath());
      }
    });
  }

  /**
   * 添加数据,当路径已经存在时会报错,初始版本号为0。第三个参数是权限控制。 <br>
   * 第四个参数,CreateMode:
   * <li>PERSISTENT:持久化保存
   * <li>PERSISTENT_SEQUENTIAL:持久化保存,并且路径附加一个自动增长的序号
   * <li>EPHEMERAL:临时数据,客户端断开连接时自动删除数据(dubbo就是采用这种机制)
   * <li>EPHEMERAL_SEQUENTIAL:客户端断开连接时自动删除数据,并且路径会附加一个自动增长的序号
   * <li>CONTAINER:
   * <li>PERSISTENT_WITH_TTL:客户端断开连接时自动删除数据,当节点在指定时间没有被修改且没有子目录时,数据会被删除
   * <li>PERSISTENT_SEQUENTIAL_WITH_TTL:客户端断开连接时自动删除数据,路径会附加一个自动增长的序号,且当节点在指定时间没有被修改且没有子目录时,数据会被删除
   */
  @Order(1)
  @Test
  public void create() {
    try {
      String back = zooKeeper.create(path, "这是一个测试".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
      logger.info("添加一条数据成功,实际路径:{}", back);
    } catch (Exception e) {
      logger.error("调用create出错", e);
    }
  }

  /**
   * 判断路径是否存在,不存在时返回null
   */
  @Order(2)
  @Test
  public void exists() {
    try {
      Stat stat = zooKeeper.exists(path, false);
      logger.info("路径为{}的节点{}存在", path, stat == null ? "不" : "");
    } catch (Exception e) {
      logger.error("调用exists出错", e);
    }
  }

  /**
   * 查询数据,路径不存在时会报错
   */
  @Order(3)
  @Test
  public void find() {
    try {
      byte[] bits = zooKeeper.getData(path, false, new Stat()); // 路径不存在时会报错
      String data = new String(bits);
      logger.info("路径{}查询到数据:{}", path, data);
    } catch (Exception e) {
      logger.error("调用getData出错", e);
    }
  }

  /**
   * 获取子目录,结果为空时返回一个长度为0的ArrayList
   */
  @Order(3)
  @Test
  public void children() {
    try {
      List<String> list = zooKeeper.getChildren(path, false);
      logger.info("路径{}的子目录有:{}", path, String.join("、", list.toArray(new String[0])));
    } catch (Exception e) {
      logger.error("调用getChildren出错", e);
    }
  }

  /**
   * 修改数据,路径不存在时会报错,版本号与存储中不一致时也报错
   */
  @Order(4)
  @Test
  public void udpate() {
    try {
      Stat stat = zooKeeper.exists(path, false);
      if (stat != null) {
        stat = zooKeeper.setData(path, "这是一个修改测试".getBytes(), stat.getVersion()); // 版本号为-1时不做版本校验
        logger.info("数据修改成功,原版本号:{},新版本号:{}", stat.getAversion(), stat.getVersion());
      }
    } catch (Exception e) {
      logger.error("调用setData出错", e);
    }
  }

  /**
   * 删除节点,路径不存在时报错,版本号不一致时也会报错
   */
  @Order(5)
  @Test
  public void delete() {
    try {
      zooKeeper.delete(path, -1); // -1表示不做版本校验
      logger.info("根据path删除数据成功");
    } catch (Exception e) {
      logger.error("调用delete出错", e);
    }
  }

  @AfterAll
  public void destory() throws Exception {
    if (zooKeeper != null) {
      zooKeeper.close();
    }
  }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • IDEA 2021版新建Maven、TomCat工程的详细教程

    IDEA 2021版新建Maven、TomCat工程的详细教程

    这篇文章主要介绍了IDEA 2021版新建Maven、TomCat工程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • MyBatis-Plus中公共字段的统一处理的实现

    MyBatis-Plus中公共字段的统一处理的实现

    在开发中经常遇到多个实体类有共同的属性字段,这些字段属于公共字段,本文主要介绍了MyBatis-Plus中公共字段的统一处理的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-08-08
  • Java修饰符 abstract,static,final 的区别详解

    Java修饰符 abstract,static,final 的区别详解

    以下是对Java修饰符abstract,static,final的区别进行了详细的介绍,需要的朋友可以过来参考下
    2013-09-09
  • Java_Spring之基于注解的 AOP 配置

    Java_Spring之基于注解的 AOP 配置

    这篇文章主要介绍了Java_Spring中基于注解的AOP配置,我们要先进行环境的搭建,在进行注解配置,感兴趣的同学可以参考阅读
    2023-04-04
  • Java实现动态生成GIF图像详解

    Java实现动态生成GIF图像详解

    在互联网上有许多有趣的场景,其中的一种就是动图。这不是视频,而是一种GIF图像信息。本文将利用Java实现动态生成GIF图像功能,需要的可以参考一下
    2022-09-09
  • SpringBoot+easypoi实现数据的Excel导出

    SpringBoot+easypoi实现数据的Excel导出

    这篇文章主要为大家详细介绍了SpringBoot+easypoi实现数据的Excel导出,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • Java中的Random()函数及两种构造方法

    Java中的Random()函数及两种构造方法

    Java中存在着两种Random函数分别是java.lang.Math.Random和java.util.Random,文中给大家介绍了random()的两种构造方法,感兴趣的朋友跟随小编一起看看吧
    2018-11-11
  • Java对象初始化顺序的使用

    Java对象初始化顺序的使用

    本篇文章介绍了,Java对象初始化顺序的使用。需要的朋友参考下
    2013-04-04
  • Spring Boot jar 启动时设置环境参数的操作

    Spring Boot jar 启动时设置环境参数的操作

    这篇文章主要介绍了Spring Boot jar 启动时设置环境参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • JAVA实现数字大写金额转换的方法

    JAVA实现数字大写金额转换的方法

    这篇文章主要介绍了JAVA实现数字大写金额转换的方法,涉及java针对字符串与数组的遍历与转换相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论