Zookeeper开源客户端Curator之基本功能讲解

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: Zookeeper开源客户端Curator之基本功能讲解

简介

Curator是Netflix公司开源的一套Zookeeper客户端框架。了解过Zookeeper原生API都会清楚其复杂度。Curator帮助我们在其基础上进行封装、实现一些开发细节,包括接连重连、反复注册Watcher和NodeExistsException等。目前已经作为Apache的顶级项目出现,是最流行的Zookeeper客户端之一。从编码风格上来讲,它提供了基于Fluent的编程风格支持。


除此之外,Curator还提供了Zookeeper的各种应用场景:Recipe、共享锁服务、Master选举机制和分布式计数器等。


image.png项目及依赖

关于项目的介绍信息可以参考Apache官网提供的关于Curator的资料信息。项目在GitHub上的开源地址随着从Netflix转移到Apache也发生了变化。原地址为:https://github.com/Netflix/curator,新地址为:https://github.com/apache/curator


版本

目前Curator有2.x.x和3.x.x两个系列的版本,支持不同版本的Zookeeper。其中Curator 2.x.x兼容Zookeeper的3.4.x和3.5.x。而Curator 3.x.x只兼容Zookeeper 3.5.x,并且提供了一些诸如动态重新配置、watch删除等新特性。


项目组件

名称 描述

Recipes Zookeeper典型应用场景的实现,这些实现是基于Curator Framework。

Framework Zookeeper API的高层封装,大大简化Zookeeper客户端编程,添加了例如Zookeeper连接管理、重试机制等。

Utilities 为Zookeeper提供的各种实用程序。

Client Zookeeper client的封装,用于取代原生的Zookeeper客户端(ZooKeeper类),提供一些非常有用的客户端特性。

Errors Curator如何处理错误,连接问题,可恢复的例外等。

Maven依赖

Curator的jar包已经发布到Maven中心,由以下几个artifact的组成。根据需要选择引入具体的artifact。但大多数情况下只用引入curator-recipes即可。


GroupID/Org ArtifactID/Name 描述

org.apache.curator curator-recipes 所有典型应用场景。需要依赖client和framework,需设置自动获取依赖。

org.apache.curator curator-framework 同组件中framework介绍。

org.apache.curator curator-client 同组件中client介绍。

org.apache.curator curator-test 包含TestingServer、TestingCluster和一些测试工具。

org.apache.curator curator-examples 各种使用Curator特性的案例。

org.apache.curator curator-x-discovery 在framework上构建的服务发现实现。

org.apache.curator curator-x-discoveryserver 可以喝Curator Discovery一起使用的RESTful服务器。

org.apache.curator curator-x-rpc Curator framework和recipes非java环境的桥接。

根据上面的描述,开发人员大多数情况下使用的都是curator-recipes的依赖,此依赖的maven配置如下:


<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.12.0</version>
</dependency>

由于版本兼容原因,采用了2.x.x的最高版本。


案例及功能说明

创建会话

Curator的创建会话方式与原生的API和ZkClient的创建方式区别很大。Curator创建客户端是通过CuratorFrameworkFactory工厂类来实现的。其中,此工厂类提供了三种创建客户端的方法。

前两种方法是通过newClient来实现,仅参数不同而已。

public static CuratorFramework newClient(String connectString, RetryPolicy retryPolicy)
public static CuratorFramework newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy)

使用上面方法创建出一个CuratorFramework之后,需要再调用其start()方法完成会话创建。

实例代码:


RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);

       CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181",retryPolicy);

       client.start();


RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);

CuratorFramework client = CuratorFrameworkFactory.newClient("127.0.0.1:2181",

               5000,1000,retryPolicy);

        client.start();


其中参数RetryPolicy提供重试策略的接口,可以让用户实现自定义的重试策略。默认提供了以下实现,分别为ExponentialBackoffRetry、BoundedExponentialBackoffRetry、RetryForever、RetryNTimes、RetryOneTime、RetryUntilElapsed。


进一步查看源代码可以得知,其实这两种方法内部实现一样,只是对外包装成不同的方法。它们的底层都是通过第三个方法builder来实现的。

实例代码:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
        CuratorFramework client =CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181")
                .retryPolicy(retryPolicy)
                .sessionTimeoutMs(6000)
                .connectionTimeoutMs(3000)
                .build();
        client.start();

观察上面的实例,我们可以看到此处已经使用了Fluent风格的编码。其中namespace(“demo”)这项设置用来定义此会话的独立命名空间,随后的相应操作都是在此命名空间下进行操作。


重试策略

上面的例子中使用到了ExponentialBackoffRetry重试策略实现。此策略先给定一个初始化sleep时间baseSleepTimeMs,在此基础上结合重试次数,通过以下代码计算当前需要的sleep时间:


long sleepMs = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)));

if ( sleepMs > maxSleepMs ){

           sleepMs = maxSleepMs;

}


随着重试次数的增加,计算出的sleep时间也会越来越大。如果超过maxSleepMs则使用maxSleepMs的时间。其中maxRetries限制了最大的尝试次数。


创建节点

Curator创建节点的方法也是基于Fluent风格编码,原生API中的参数很多都转化为一层层的方法调用来进行设置。下面简单介绍一下常用的几个节点创建场景。

(1)创建一个初始内容为空的节点


client.create().forPath(path);


Curator默认创建的是持久节点,内容为空。

(2)创建一个包含内容的节点


client.create().forPath(path,"我是内容".getBytes());


Curator和ZkClient不同的是依旧采用Zookeeper原生API的风格,内容使用byte[]作为方法参数。

(3)创建临时节点,并递归创建父节点


client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);


此处Curator和ZkClient一样封装了递归创建父节点的方法。在递归创建父节点时,父节点为持久节点。


删除节点

删除节点的方法也是基于Fluent方式来进行操作,不同类型的操作调用新增不同的方法调用即可。

(1)删除一个子节点


client.delete().forPath(path);


(2)删除节点并递归删除其子节点


client.delete().deletingChildrenIfNeeded().forPath(path);


(3)指定版本进行删除


client.delete().withVersion(1).forPath(path);


如果此版本已经不存在,则删除异常,异常信息如下。


org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for


(4)强制保证删除一个节点


client.delete().guaranteed().forPath(path);


只要客户端会话有效,那么Curator会在后台持续进行删除操作,直到节点删除成功。比如遇到一些网络异常的情况,此guaranteed的强制删除就会很有效果。


读取数据

读取节点数据内容API相当简单,Curator提供了传入一个Stat,使用节点当前的Stat替换到传入的Stat的方法,查询方法执行完成之后,Stat引用已经执行当前最新的节点Stat。

// 普通查询
client.getData().forPath(path);
// 包含状态查询
Stat stat = new Stat();
client.getData().storingStatIn(stat()).forPath(path);

更新数据

更新数据,如果未传入version参数,那么更新当前最新版本,如果传入version则更新指定version,如果version已经变更,则抛出异常。


// 普通更新

client.setData().forPath(path,"新内容".getBytes());

// 指定版本更新

client.setData().withVersion(1).forPath(path);


版本不一直异常信息:


org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for


异步接口

在使用以上针对节点的操作API时,我们会发现每个接口都有一个inBackground()方法可供调用。此接口就是Curator提供的异步调用入口。对应的异步处理接口为BackgroundCallback。此接口指提供了一个processResult的方法,用来处理回调结果。其中processResult的参数event中的getType()包含了各种事件类型,getResultCode()包含了各种响应码。


重点说一下inBackground的以下接口:


public T inBackground(BackgroundCallback callback, Executor executor);


此接口就允许传入一个Executor实例,用一个专门线程池来处理返回结果之后的业务逻辑。


相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
2月前
|
存储 缓存 Java
【Zookeeper】Apach Curator 框架源码分析:后台构造器和节点操作相关源码分析(二)【Ver 4.3.0】
【Zookeeper】Apach Curator 框架源码分析:后台构造器和节点操作相关源码分析(二)【Ver 4.3.0】
19 0
|
3月前
|
安全 Java API
Zookeeper(持续更新) VIP-02 Zookeeper客户端使用与集群特性
2,/usr/local/data/zookeeper-3,/usr/local/data/zookeeper-4,在每个目录中创建文件。创建四个文件夹/usr/local/data/zookeeper-1,/usr/local/data/zookeeper-Follower:只能处理读请求,同时作为 Leader的候选节点,即如果Leader宕机,Follower节点。己对外提供服务的起始状态。E: 角色, 默认是 participant,即参与过半机制的角色,选举,事务请求过半提交,还有一个是。
|
3月前
Zookeeper的客户端的命令
Zookeeper的客户端的命令
18 0
|
3月前
|
缓存 Java API
Zookeeper(持续更新) VIP-02 Zookeeper客户端使用与集群特性
Curator 是一套由netflix 公司开源的,Java 语言编程的 ZooKeeper 客户端框架,Curator项目是现在ZooKeeper 客户端中使用最多,对ZooKeeper 版本支持最好的第三方客户端,并推荐使用,Curator 把我们平时常用的很多 ZooKeeper 服务开发功能做了封装,例如 Leader 选举、分布式计数器、分布式锁。这就减少了技术人员在使用 ZooKeeper 时的大部分底层细节开发工作。
|
3月前
|
Apache
Apache ZooKeeper - 构建ZooKeeper源码环境及StandAlone模式下的服务端和客户端启动
Apache ZooKeeper - 构建ZooKeeper源码环境及StandAlone模式下的服务端和客户端启动
45 2
|
4月前
|
存储 设计模式 算法
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
当我们向zk发出一个数据更新请求时,这个请求的处理流程是什么样的?zk又是使用了什么共识算法来保证一致性呢?带着这些问题,我们进入今天的正文。
136 1
深入浅出Zookeeper源码(六):客户端的请求在服务器中经历了什么
|
7天前
|
监控 负载均衡 Cloud Native
ZooKeeper分布式协调服务详解:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入剖析ZooKeeper分布式协调服务原理,涵盖核心概念如Server、Client、ZNode、ACL、Watcher,以及ZAB协议在一致性、会话管理、Leader选举中的作用。讨论ZooKeeper数据模型、操作、会话管理、集群部署与管理、性能调优和监控。同时,文章探讨了ZooKeeper在分布式锁、队列、服务注册与发现等场景的应用,并在面试方面分析了与其它服务的区别、实战挑战及解决方案。附带Java客户端实现分布式锁的代码示例,助力提升面试表现。
28 2
|
3月前
|
消息中间件 Java 网络安全
JAVAEE分布式技术之Zookeeper的第一次课
JAVAEE分布式技术之Zookeeper的第一次课
70 0
|
1月前
|
监控 NoSQL Java
Zookeeper分布式锁
Zookeeper分布式锁
90 1
|
3月前
|
监控 Dubbo Java
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
深入理解Zookeeper系列-2.Zookeeper基本使用和分布式锁原理
58 0