【ZookeeperApach Curator 框架源码分析:后台构造器和节点操作相关源码分析(二)【Ver 4.3.0

2023年 7月 22日 36.5k 0

引言

本文介绍后台任务延迟队列的“元素” 后台任务构造器 以及Curator 对于常见的ZK节点操作封装API。后台任务构造器对应了和ZK交互的常见”后台“操作,比如创建和销毁Watch,而ZK节点操作API涉及各种建造者模式的应用。可以说,Curator 整个框架各种地方都有建造者模式的身影。

Curator除了对于ZK本身交互和操作封装之外,还引入了Cache的概念来实现对ZooKeeper服务器端进行事件监听,本质上就是构建本地缓存,在远程节点出现”状态“变动的时候进行”联动“触发各种事件。

不过,Cache 的部分个人认为并不是很重要的内容,更多重心还是在分布式锁,再加上查询各种资料本身应用场景也比较少,因此放到了文章最后分析,读者可以按需阅读。

相关应用场景和重要概念

本文的源码分析涉及到 ZK 的应用场景和重要概念,这里先补充相关概念,为后面的源码分析铺垫。

相关应用场景

ZK 中可以完成数据发布订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举,分布式锁和分布式队列。

命名服务: 使用 ZooKeeper 的顺序节点生成全局唯一 ID。

数据发布/订阅:通过 Watcher 机制 可以很方便地实现数据发布/订阅。

分布式锁:通过创建唯一节点获得分布式锁,通常会使用临时节点的方式持有锁,特点是在节点宕机之后会自动释放。

重要概念

ZNode 概念

Zookeeper 的数据模型使用的是多叉树结构,每个节点上面可以存储任意类型的数据,比如数组、字符串、二进制序列。由于是树状节点,每个节点还可以有子节点。

树状节点的组成每个节点可以有N个子节点,根节点为 "/",每个数据节点在Zookeeper中都被叫做ZNode,整个树的组成有点类似Linux的文件系统结构。

image.png

注意 ZNode 通常用于临时创建,适合用于比较小体积的锁应用,不建议存储过大的业务数据,不要把过大的数据放到 ZNode上。

ZNode 数据节点

Zookeeper 的数据节点 ZNode 是最小组成单元,ZNode 是 ZK 实现分布式锁的重要基础,它主要有如下分类:

  • 持久(PERSISTENT)节点:一旦创建就会一直存在,直到 ZK集群宕机才会删除。
  • 临时(EPHEMERAL)节点:临时节点的生命周期是与 客户端会话(session) 绑定,会话消失则节点消失,
  • 持久顺序(PERSISTENT_SEQUENTIAL)节点:在持久节点的特性上,子节点的名称依然有顺序性,比如 /node1/app0000000001/node1/app0000000002 。
  • 临时顺序(EPHEMERAL_SEQUENTIAL)节点:除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性。

Watcher(事件监听器)

Watcher 事件监听器是 Zookeeper 当中非常重要的特性,ZK 允许用户在指定的 Znode 上面注册监听器 Watcher,特定的事件触发时候,ZK服务端会把事件通知到注册Watcher的客户端,。事件监听器也是分布式协调服务的重要组成部分。

在 Curator 中,Watcher 事件监听器是不同客户端监听分布式锁释放的重要应用组件。

ZK可视化客户端 PrettyZoo

为了方便我们调试源码的同时观察ZK节点变更,这里推荐使用 PrettyZoo 客户端。

PrettyZoo 是一个基于 Apache Curator 和 JavaFX 实现的 Zookeeper 图形化管理客户端。使用了 Java 的模块化(Jigsaw)技术,并基于 JPackage 打包了多平台的可运行文件(无需要额外安装 Java 运行时)。

目前已提供了 mac(dmg 文件)、Linux(deb 和 rpm 文件)、windows(msi 文件) 的安装包,下载地址。

image.png

个人为Win系统,选择win.msi 的安装包,安装并启动并且就进入到主页面

image.png

完成配置之后进行连接,最终的连接效果如图:

image.png

前面的铺垫已经完成,下面正式进入主题。

后台任务构造器

在[【Zookeeper】Apach Curator 框架源码分析:初始化过程(一)【Ver 4.3.0】]当中,我们介绍了Curator实例化、Zookeeper连接以及各种组件初始化和启动过程,其中就有一个后台执行操作队列不断执行后台操作。

image.png

OperationAndData中的 BackgroundOperation ,封装各种常见ZK指令的构造器。

image.png

下面以 BackgroundOperation 作为切入点,看看它的构造器是如何实现的?

后台操作接口 BackgroundOperation

BackgroundOperation 是后台操作接口的 顶级接口,其中只有一个方法,它接收 OperationAndData 作为请求参数。

org.apache.curator.framework.imps.BackgroundOperation

interface BackgroundOperation  
{  
    public void performBackgroundOperation(OperationAndData data) throws Exception;  
}

这种设计让我联想到 Executor 的设计(略显牵强),Runnable 是线程的执行操作分离抽象,与之对应的OperationAndData是对于后台操作的抽象。

public interface Executor {  
     void execute(Runnable command);  
}

后台事件数据对象 OperationAndData

org.apache.curator.framework.imps.OperationAndData

OperationAndData 对象的代码略多,这里拆分介绍,首先来看下继承结构, OperationAndData 最终被存储在后台线程执行的操作队列backgroundOperations,backgroundOperations使用JDK原生并发延迟队列DelayQueue作为基础。

按照 DelayQueue 的设计存储要求,内部元素必须实现Delayed接口以支持延迟操作,除此之外, OperationAndData 还实现了 RetrySleeper 接口,从英文名称也可以大致猜出它是 对重试政策的抽象化。

class OperationAndData implements Delayed, RetrySleeper
//后台线程执行的操作队列
backgroundOperations = new DelayQueue

相关文章

JavaScript2024新功能:Object.groupBy、正则表达式v标志
PHP trim 函数对多字节字符的使用和限制
新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
为React 19做准备:WordPress 6.6用户指南
如何删除WordPress中的所有评论

发布评论