Zookeeper之Java客户端实战

        ZooKeeper应用的开发主要通过Java客户端API去连接和操作ZooKeeper集群。可供选择的Java客户端API有:

  • ZooKeeper官方的Java客户端API。
  • 第三方的Java客户端API,比如Curator。

        接下来我们将逐一学习一下这两个java客户端是如何操作zookeeper的。

1. ZooKeeper官方的Java客户端

1.1 简介

        ZooKeeper官方的客户端API提供了基本的操作。例如,创建会话、创建节点、读取节点、更新数据、删除节点和检查节点是否存在等。不过,对于实际开发来说,ZooKeeper官方API有一些不足之处,具体如下:

  • ZooKeeper的Watcher监听是一次性的,每次触发之后都需要重新进行注册。
  • 会话超时之后没有实现重连机制
  • 异常处理烦琐,ZooKeeper提供了很多异常,对于开发人员来说可能根本不知道应该如何处理这些抛出的异常。
  • 仅提供了简单的byte[]数组类型的接口,没有提供Java POJO级别的序列化数据处理接口。
  • 创建节点时如果抛出异常,需要自行检查节点是否存在
  • 无法实现级联删除

总之,ZooKeeper官方API功能比较简单,在实际开发过程中比较笨重,一般不推荐使用

1.2 基础使用

使用zookeeper原生客户端,需要引入zookeeper客户端的依赖。

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

注意:保持与服务端版本一致,不然会有很多兼容性的问题。

        ZooKeeper原生客户端主要使用org.apache.zookeeper.ZooKeeper这个类来调用ZooKeeper服务的。

1.2.1 连接zk集群

ZooKeeper构造器:

 public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher) throws IOException {
        this(connectString, sessionTimeout, watcher, false);
    }

 connectString:使用逗号分隔的列表,每个ZooKeeper节点是一个host.port对,host 是机器名或者IP地址,port是ZooKeeper节点对客户端提供服务的端口号。客户端会任意选取connectString 中的一个节点建立连接。
sessionTimeout : session timeout时间。
watcher:用于接收到来自ZooKeeper集群的事件。

    如何使用客户端构造器与服务端建立连接:

    建立连接的工具类;因为zookepper建立连接时特别慢,所以采用了CountDownLatch同步工具类,等待zookeeper客户端与服务端建立完成后,继续后续操作。

public class ZooKeeperFacotry {
    private static final int SESSION_TIMEOUT = 5000;

    public static ZooKeeper create(String connectionString) throws Exception {
        final CountDownLatch connectionLatch = new CountDownLatch(1);
        ZooKeeper zooKeeper = new ZooKeeper(connectionString, SESSION_TIMEOUT, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                if (event.getType()== Event.EventType.None
                        && event.getState() == Watcher.Event.KeeperState.SyncConnected) {
                    connectionLatch.countDown();
                    System.out.println("连接建立");
                }
            }
        });

        System.out.println("等待连接建立...");
        connectionLatch.await();

        return zooKeeper;
    }

}
public class ZkClientDemo {

    private final static  String CLUSTER_CONNECT_STR="192.168.31.5:2181,192.168.31.176:2181,192.168.31.232:2181";

    public static void main(String[] args) throws Exception {
        //创建zookeeper对象
        ZooKeeper zooKeeper = ZooKeeperFacotry.create(CLUSTER_CONNECT_STR);

        //连接
        System.out.println(zooKeeper.getState());
}

运行结果:

1.2.2 操作节点

以下是Zookeeper原生客户端操作服务端的一些主要API:

  • create(path, data, acl,createMode): 创建一个给定路径的 znode,并在 znode 保存 data[]的 数据,createMode指定 znode 的类型。
  • delete(path, version):如果给定 path 上的 znode 的版本和给定的 version 匹配, 删除 znode。
  • exists(path, watch):判断给定 path 上的 znode 是否存在,并在 znode 设置一个 watch。
  • getData(path, watch):返回给定 path 上的 znode 数据,并在 znode 设置一个 watch。
  • setData(path, data, version):如果给定 path 上的 znode 的版本和给定的 version 匹配,设置znode 数据。
  • getChildren(path, watch):返回给定 path 上的 znode 的孩子 znode 名字,并在 znode 设置一个 watch。
  • sync(path):把客户端 session 连接节点和 leader 节点进行同步。

API特点:

  • 所有获取 znode 数据的 API 都可以设置一个 watch 用来监控 znode 的变化。
  • 所有更新 znode 数据的 API 都有两个版本: 无条件更新版本和条件更新版本。如果 version 为 -1,更新为无条件更新。否则只有给定的 version 和 znode 当前的 version 一样,才会进行更新,这样的更新是条件更新。
  • 所有的方法都有同步和异步两个版本。同步版本的方法发送请求给 ZooKeeper 并等待服务器的响 应。异步版本把请求放入客户端的请求队列,然后马上返回。异步版本通过 callback 来接受来 自服务端的响应。

接下来,我们利用这些API对zk的节点进行简单的操作

1.2.2.1 创建持久节点

代码:

public class ZkClientDemo {

    private final static  String CLUSTER_CONNECT_STR="192.168.31.5:2181,192.168.31.176:2181,192.168.31.232:2181";

    public static void main(String[] args) throws Exception {
        //创建zookeeper对象
        ZooKeeper zooKeeper = ZooKeeperFacotry.create(CLUSTER_CONNECT_STR);

        //连接
        System.out.println(zooKeeper.getState());

        Stat stat = zooKeeper.exists("/order",false);
        if(null ==stat){
            //创建持久节点
            zooKeeper.create("/order","001".getBytes(),
                    ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        }
         System.out.println("执行完了");
}

 运行的结果:

我们在服务器的客户端查看一下数据:

有数据,创建成功了。 

1.2.2.2 永久监听节点

代码:

public class ZkClientDemo {

    private final static  String CLUSTER_CONNECT_STR="192.168.31.5:2181,192.168.31.176:2181,192.168.31.232:2181";

    public static void main(String[] args) throws Exception {
        //创建zookeeper对象
        ZooKeeper zooKeeper = ZooKeeperFacotry.create(CLUSTER_CONNECT_STR);

        //连接
        System.out.println(zooKeeper.getState());

        Stat stat = zooKeeper.exists("/order",false);


        //永久监听  addWatch -m mode
        zooKeeper.addWatch("/order",new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                System.out.println(event);
                //TODO
            }
        },AddWatchMode.PERSISTENT);
        Thread.sleep(Integer.MAX_VALUE);
}

启动程序后,在服务器的客户端修改监听的节点。 

 程序监听到 /order这个节点被修改了。

1.2.2.3 根据版本更新

代码:

public class ZkClientDemo {

    private final static  String CLUSTER_CONNECT_STR="192.168.31.5:2181,192.168.31.176:2181,192.168.31.232:2181";

    public static void main(String[] args) throws Exception {
        //创建zookeeper对象
        ZooKeeper zooKeeper = ZooKeeperFacotry.create(CLUSTER_CONNECT_STR);

        //连接
        System.out.println(zooKeeper.getState());

        Stat stat = zooKeeper.exists("/order",false);

        stat = new Stat();
        byte[] data = zooKeeper.getData("/order", false, stat);
        System.out.println(" data: "+new String(data));
        // -1: 无条件更新
        //zooKeeper.setData("/user", "third".getBytes(), -1);
        // 带版本条件更新
        int version = stat.getVersion();

        zooKeeper.setData("/order", "updateByVersion".getBytes(), version);
        
        Thread.sleep(Integer.MAX_VALUE);

    }

}

第一次打印的数据结果: 

待程序执行完,在服务器客户端查询的结果:更具版本更新数据成功了。

        对于zookeeper java原生客户端的使用,就简单介绍这么多,不在过多赘述,只是为了是让大家感受一下,原生客户端的使用。实际开发中并不推荐使用zk的原生客户端,过于笨重。

2. 开源的第三方客户端:Curator

2.1 简介

        官网:https://curator.apache.org/

        Curator是Netflix公司开源的一套ZooKeeper客户端框架,和ZkClient一样它解决了非常底层的细节开发工作,包括连接、重连、反复注册Watcher的问题以及NodeExistsException异常等。
        Curator是Apache基金会的顶级项目之一,Curator具有更加完善的文档,另外还提供了一套易用性和可读性更强的Fluent风格的客户端API框架。
        Curator还为ZooKeeper客户端框架提供了一些比较普遍的、开箱即用的、分布式开发用的解决方案,例如Recipe、共享锁服务、Master选举机制和分布式计算器等,帮助开发者避免了“重复造轮子”的无效开发工作。

        在实际的开发场景中,使用Curator客户端就足以应付日常的ZooKeeper集群操作的需求。

2.2 基础使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/286883.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2.4信道复用技术

目录 2.4信道复用技术2.4.1频分复用、时分复用和统计时分复用频分复用FDM&#xff08;Frequency Division Multiplexing&#xff09;时分复用TDM&#xff08;Time Division Multiplexing&#xff09;统计时分复用STDM&#xff08;Statistic TDM&#xff09; 2.4.2波分复用2.4.3…

IIS通过ARR实现负载均衡

一、实现整体方式介绍 项目中部署在windows服务器上的项目,需要部署负载均衡,本来想用nginx来配置的,奈何iis上有几个项目,把80端口和443端口占用了,nginx就用不了了(因为通过域名访问的,必须要用80和443端口),只能通过IIS的方式实现了。 这里用2个服务在一台机器上…

mysql: 2006, ‘MySQL server has gone away‘

一、错误问题 这个问题是在迁移数据库、备份还原或数据导入时报错&#xff1a;2006, ‘MySQL server has gone away‘ 二、出现原因 sql操作的时间过长&#xff0c;或者是传送的数据太大(例如使用insert ... values的语句过长&#xff0c; 这种情况可以通过修改max_allowed_pac…

魔改Stable Diffusion,开源创新“单目深度估计”模型

单目深度估计一直是计算机视觉领域的难点。仅凭一张 RGB 图像,想要还原出场景的三维结构,在几何结构上非常不确定,必须依赖复杂的场景理解能力。 即便使用更强大的深度学习模型来实现&#xff0c;也面临算力需求高、图像数据注释量大、泛化能力弱等缺点。 为了解决这些难题&a…

C# WinForm MessageBox自定义按键文本 COM组件版

c# 更改弹窗MessageBox按钮文字_c# messagebox.show 字体-CSDN博客 需要用到大佬上传到百度云盘的Hook类&#xff0c;在大佬给的例子的基础上改动了点。 加了ok按键&#xff0c;还原了最基础的messageBox。 为了适配多语言&#xff0c;增加ReadBtnLanguge方法。 应用时自己…

rime中州韵 inputShow lua Filter

在 rime中州韵 inputShow lua Translator 一文中&#xff0c;我们通过 inputShow.lua 定制了 inputShow_translator&#xff0c;这使得我们的输入方案可以将用户输入的字符透传到候选列表中来。如下&#x1f447;&#xff1a; &#x1f446;上图中我们在候选列表中看到了 inpu…

vmware安装龙蜥操作系统

vmware安装龙蜥操作系统 1、下载龙蜥操作系统 8.8 镜像文件2、安装龙蜥操作系统 8.83、配置龙蜥操作系统 8.83.1、配置静态IP地址 和 dns3.2、查看磁盘分区3.3、查看系统版本 1、下载龙蜥操作系统 8.8 镜像文件 这里选择 2023年2月发布的 8.8 版本 官方下载链接 https://mirro…

计算机网络-以太网交换基础

一、网络设备的演变 最初的网络在两台设备间使用传输介质如网线等进行连接就可以进行通信。但是随着数据的传输需求&#xff0c;多个设备需要进行数据通信时就需要另外的设备进行网络互联&#xff0c;并且随着网络传输的需求不断更新升级。从一开始的两台设备互联到企业部门内部…

如何在iPhone设备中查看崩溃日志

​ 目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么&#xff1f; 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志&#xff0c;以便调查崩溃的原因。我们将展示三种不同的…

QQ邮件发送(PHP的Laravel)

1. 开启 QQ 邮箱的 SMTP 支持 2.里面会一个类似于密码之类&#xff08;复制一下&#xff09; 3.然后再 .env文件里面配置一下 MAIL_DRIVERsmtp —— 使用支持 ESMTP 的 SMTP 服务器发送邮件&#xff1b; MAIL_HOSTsmtp.qq.com —— QQ 邮箱的 SMTP 服务器地址&#xff0c;必…

欢迎提交pr共同改进项目, pr的含义?

"提交PR"在软件开发和编程领域是一个常用术语&#xff0c;特别是在使用版本控制系统如Git时。这里的“PR”指的是“Pull Request”&#xff0c;它是一种通知项目维护人员您已经完成了一些代码改动并希望将这些改动合并到主项目中的方式。简单来说&#xff0c;当您对一…

《3D数学基础-图形和游戏开发》阅读笔记 | 3D数学基础 (学习中)

文章目录 3D数学基础矢量/向量概述 - 什么是向量单位矢量&#xff1a;只关注方向不关注大小 数学运算矢量的加法与减法减法的几何意义计算一个点到另一个点的位移矢量的点积与叉积 矩阵矩阵的几何意义 3D数学基础 矢量/向量 在笔记中 变量使用小写字母表示&#xff0c;a由于…

内存管理机制

内存管理机制与内存映射相关。 一、C与C 之所以将C与C放在一起是因为C是C的超集&#xff1b; 但是C是面向过程语言&#xff0c;C是面向对象的语言&#xff1b; C与C都可以使用malloc、calloc、realloc来申请内存空间&#xff1b; 其中void* malloc(size_t size)是在内存的动态…

【 C语言 】| C程序百例 - 绘制余弦曲线

【 C语言 】| C程序百例 - 绘制余弦曲线 时间&#xff1a;2023年12月29日12:56:29 文章目录 【 C语言 】| C程序百例 - 绘制余弦曲线1.要求2.问题分析与算法设计3.程序3-1.源码3-2.makefile 4.运行 1.要求 在屏幕上用"*"显示0~360的余弦曲线cos(x)曲线。 2.问题分析与…

【python】—— 列表和元组详解

Python是一种强大的编程语言&#xff0c;它提供了许多内置的数据结构&#xff0c;用于存储和处理数据。其中&#xff0c;列表和元组是两种常用的数据类型。这篇文章将介绍这两种数据结构的定义、用途、用法以及它们的异同点。 目录 &#xff08;一&#xff09;理解列表和元组 …

Neuro Contamination - Cyberpunk Gaming Music Futuristic Glitchy Sci-fi

无论是展示赛博朋克未来的电影场景&#xff0c;还是介绍高科技武器&#xff0c;你的音乐选择都至关重要。这首曲子的灵感来自科幻小说&#xff0c;旨在让你的观众想象未来的感觉。 潜在用例&#xff1a;科幻游戏、赛博朋克游戏、电影预告片、动作场景和产品广告。 非常适合充…

Simple Facebook Sign-In

简单的Facebook登录为Android、iOS、Windows、Mac、通用Windows平台(UWP)和Unity制作的WebGL应用程序提供了基于OAuth 2.0的Facebook登录。 优点: ● 跨平台游戏和应用程序的跨平台用户身份验证 ● 无插件,无第三方库,无依赖● 对建筑规模没有影响 ● 客户端-服务器应…

[Flutter]WindowsOS中相关配置

Flutter项目在Windows平台上如何配置 目录 Flutter项目在Windows平台上如何配置 写在开头 正文 1、OS准备 2、编译环境准备 ① 下载AndroidStudio ② 下载dart ③ 下载flutter ④ 下载并安装VS ⑤ 在AS中配置dart和flutter 3、配置中遇到的问题 写在结尾 写在开头…

开发辅助三(缓存Redisson分布式锁+分页插件)

缓存 缓存穿透&#xff1a;查询一个不存在的数据&#xff0c;由于缓存不命中&#xff0c;将大量查询数据库&#xff0c;但是数据库也没有此记录。 没有将这次查询的null写入缓存&#xff0c;导致了这个不存在的数据每次请求都要到存储层查询&#xff0c;失去了缓存的意义。 解…

地平面--高速布线

https://baijiahao.baidu.com/s?id1764139038516816855&wfrspider&forpc 概念 回顾传输线&#xff0c;由任意两条有一定长度的导线组成&#xff0c;一条为信号路径&#xff0c;一条为返回路径。基本电路理论告诉我们&#xff0c;信号是由电流传播的&#xff0c;明确的…