【分布式技术专题】「Zookeeper中间件」给大家学习一下Zookeeper的”开发伴侣”—Curator-Framework(基础篇)

news2025/7/20 20:48:56

CuratorFramework基本介绍

CuratorFramework是Netflix公司开源的一套Zookeeper客户端框架,它作为一款优秀的ZooKeeper客户端开源工具,主要提供了对客户端到服务的连接管理和连接重试机制,以及一些扩展功能,它解决了很多ZooKeeper客户端非常底层的细节开发工作。

主要的功能包括:连接重连、反复注册Watcher和NodeExistsException异常等,目前已经成为了Apache的顶级项目,是全世界范围内使用最广泛的ZooKeeper客户端之一,Patrick Hunt(ZooKeeper代码的核心提交者)以一句 “Guava is to Java what Curator is to ZooKeeper” (Curator对于ZooKeeper,可以说就像Guava工具集对于Java平台一样,作用巨大)对其进行了高度评价。

除此之外,Curator中还提供了ZooKeeper各种应用场景(Recipe,如共享锁服务、Master选举机制和分布式计数器等)的抽象封装。

CuratorFramework编程特点

除了封装一些开发人员不需要特别关注的底层细节之外,Curator还在ZooKeeper原生API的基础上进行了包装,提供了一套易用性和可读性更强的Fluent风格的客户端API框架。

CuratorFramework项目组件

  • Recipes:Zookeeper典型应用场景的实现,这些实现是基于Curator Framework。
  • Framework:Zookeeper API的高层封装,简化Zookeeper客户端编程,添加了例如Zookeeper连接管理、重试机制等。
  • Utilities:为Zookeeper提供的各种实用程序。
  • Client:Zookeeper client的封装,用于取代原生的Zookeeper客户端(ZooKeeper类),提供一些非常有用的客户端特性。
  • Errors:Curator如何处理错误,连接问题,可恢复的例外等。

官方资源

  • 官方文档
  • 版本列表
  • 官方文章

Maven依赖说明

由以下几个artifact的组成,但大多数情况下只用引入curator-recipes即可。

CuratorFramework简单使用

CuratorFramework的jar包在Maven仓库中心是可以找到 ,使用Maven,Gradle,Ant等可以很轻松简单的将Curator包含到项目当中。

很多用户会想要使用Curtor预编译的一些工具,所以Curator提供了curator-recipes,如果你仅仅想使用Zooeeper的简单包装,包括链接管理和重试机制,那么使用curator-framework就足够了。

Maven依赖配置

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

创建会话

使用CuratorFrameworkFactory这个工厂类的两个静态方法来创建一个客户端:

static CuratorFramework newClient(String connectString, RetryPolicy retryPolicy);
static CuratorFramework newClient(String connectString, int sessionTimeoutMs, int connectionTimeoutMs, RetryPolicy retryPolicy);
构造方法中的各参数

  • connectString:zk的server地址,多个server之间使用英文逗号分隔开

  • connectionTimeoutMs:连接超时时间,如上是30s,默认是15s

  • sessionTimeoutMs:会话超时时间,如上是50s,默认是60s

  • retryPolicy:失败重试策略

Session会话超时

该方法配置重连retryPolicy以及回话有效时间sessionTimeoutMs,重连就是当客户端与zookeeper 连接异常的时候,如网络波动,断开链接,支持重新连接,会话有效这个与节点的属性有关。那么zookeeper 有哪些节点属性。

重试策略

CuratorFramework通过一个接口RetryPolicy来让用户实现自定义的重试策略。在RetryPolicy来让用户实现自定义的重试策略。在RetryPolicy接口中定义了一个方法:

boolean allowRetry(int retryCount, long elapsedTimeMs, RetrySleeper sleeper)
RetryPolicy接口参数

默认提供了以下实现,分别为ExponentialBackoffRetry、BoundedExponentialBackoffRetry、RetryForever、RetryNTimes、RetryOneTime、RetryUntilElapsed。

通过调用CuratorFramework中的start()方法来启动会话。

获取Zookeeper连接会话

Curator链接实例(CuratorFramework)由CuratorFrameworkFactory获取,对于一个Zk集群,仅仅需要一个CuratorFramework实例:

RetryPolicy retryPolicy  = new ExponentialBackoffRetry(1000,3);
CuratorFramework Client = CuratorFrameworkFactory.builder()
            .connectString("ip:2181,ip2:2181,ip3:2181")
            .sessionTimeoutMs(3000)
            .connectionTimeoutMs(5000)
            .retryPolicy(retryPolicy)
            .build();
client.start();
client.blockUntilConnected();

这将会使用默认的值创建一个到ZK集群的链接,唯一需要特别指定单参数是重试机制,从例子上看,你需要使用:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3); 
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();

获得到的CuratorFramework实例在使用之前需要调用其start方法,在不许要使用的时候需要调用close方法。

在上面这个示例程序中,我们首先创建了一个名为ExponentialBackoffRetry的重试策略,该重试策略是Curator默认提供的几种重试策略之一,其构造方法如下:

ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries);
ExponentialBackOffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs);

ExponentialBackoffRetry构造方法参数:

构造器含有三个参数 ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)

  • baseSleepTimeMs:初始的sleep时间,用于计算之后的每次重试的sleep时间,计算公式:当前sleep时间=baseSleepTimeMs*Math.max(1, random.nextInt(1<<(retryCount+1)))

  • maxRetries:最大重试次数

  • maxSleepMs:最大sleep时间,如果上述的当前sleep计算出来比这个大,那么sleep用这个时间

org.apache.curator.RetryPolicy接口

  • start() 开始创建会话。

  • blockUntilConnected() 直到连接成功或超时。

ExponentialBackoffRetry的重试策略

给定一个初始sleep时间baseSleepTimeMs,在这个基础上结合重试次数,通过以下公式计算出当前需要sleep的时间:
当前sleep时间 = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)))

随着重试次数的增加,计算出的sleep时间会越来越大。如果该sleep时间在maxSleepMs的范围之内,那么就使用该sleep时间,否则使用maxSleepMs。另外,maxRetries参数控制了最大重试次数,以避免无限制的重试。

CuratorFrameworkFactory工厂在创建出一个客户端CuratorFramework实例之后,实质上并没有完成会话的创建,而是需要调用CuratorFramework的start()方法来完成会话的创建。

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

一旦你拥有了CuratorFramework实例,你可以直接调用Zookeeper,这类似ZK发布版本中提供的原生的ZooKeeper对象,

client.create().forPath(path);
创建一个包含内容的节点
client.create().forPath(path,"数据欸日".getBytes());
创建临时节点,并递归创建父节点
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);

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

client.create().forPath("/my/path", myData)

删除节点

删除一个子节点
client.delete().forPath(path);
删除节点并递归删除其子节点
client.delete().deletingChildrenIfNeeded().forPath(path);
指定版本进行删除
client.delete().withVersion(1).forPath(path);

//如果版本不存在,则删除异常,信息如下:

org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for
强制保证删除一个节点
client.delete().guaranteed().forPath(path);

读取数据

读取节点数据内容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实例,用一个专门线程池来处理返回结果之后的业务逻辑。
/**
*  异步创建节点
*
* 注意:如果自己指定了线程池,那么相应的操作就会在线程池中执行,如果没有指定,
* 那么就会使用Zookeeper的EventThread线程对事件进行串行处理
* */
client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
        System.out.println("当前线程:" + Thread.currentThread().getName() + ",code:"
                        + event.getResultCode() + ",type:" + event.getType());
        }
    }, Executors.newFixedThreadPool(10)).forPath("/async-node01");
client.create().withMode(CreateMode.EPHEMERAL).inBackground(new BackgroundCallback() {
    public void processResult(CuratorFramework client, CuratorEvent event) throws Exception {
        System.out.println("当前线程:" + Thread.currentThread().getName() + ",code:" 
                           + event.getResultCode() + ",type:" + event.getType());
        }
    }).forPath("/async-node02");

创建含隔离命名空间的会话

使用Curator的好处是Curator帮助我们管理客户端到ZK的链接,并且在出现网络链接的问题的时候将会执行指定的重试机制。为了实现不同的ZooKeeper业务之间的隔离,往往会为每个业务分配一个独立的命名空间,即指定一个ZooKeeper根路径。

下面所示的代码片段中定义了某一个客户端的独立命名空间为/base,那么该客户端对ZooKeeper上数据节点的任何操作,都是基于该相对目录进行的:

CuratorFrameworkFactory.builder().connectString("domain1.book.zookeeper:2181")
	.sessionTimeoutMs(5000).retryPolicy(retryPolicy).namespace("base").build();

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux服务器配置与管理(基于Centos7.2)任务目标(四)

文章目录一、任务目标二、任务资讯三、任务实施3-1.RPM软件包管理3-2.YUM方式安装软件一、任务目标 实施该工单的任务目标如下&#xff1a; 知识目标 1.了解RPM提供的功能。 2.了解YUM相对于RPM所具有的优点。 能力目标 1.能够通过RPM安装及管理软件包。 2.能够通过YUM安装及管…

uni-app —— 小程序加入购物车实现过程

文章目录 前言一、示意图二、整体实现思路三、实现过程 1.加入购物车2.获取当前用户购物车信息3.解决数据获取不及时的问题总结前言 前文已经讲解了如何实现商品规格的选择&#xff0c;那么接下来就应该将用户选中的商品加入购物车啦&#xff01;那么如何实现呢&#xff1f;请…

[附源码]计算机毕业设计JAVA儒家文化网站

[附源码]计算机毕业设计JAVA儒家文化网站 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis M…

FilterListenerAjax的介绍

目录 一、Filter 1、Filter概述 2、过滤器链 二、Listener 三、Ajax 1、基本介绍 2、快速入门案例 3、axios 4、JSON 一、Filter 1、Filter概述 ▶ 过滤器 Filter 表示过滤器&#xff0c;是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。过滤器可以把对资源的请…

Centos--基于Jdk1.8环境安装+卸载Jenkins

基础准备 本人选择的安装的环境基于jdk1.8 操作系统&#xff1a;Centos7.9 java: 1.8.0_262 检查是否有旧版本 $rpm -ql jenkins 如果有老版本可以卸载后&#xff0c;再执行后面的安装步骤 卸载 jenkins $rpm -e jenkins —删除遗留文件: $find / -iname jenkins | xa…

【Lilishop商城】No2-4.确定软件架构搭建三(本篇包括ES检索)

仅涉及后端&#xff0c;全部目录看顶部专栏&#xff0c;代码、文档、接口路径在&#xff1a; 【Lilishop商城】记录一下B2B2C商城系统学习笔记~_清晨敲代码的博客-CSDN博客 全篇只介绍重点架构逻辑&#xff0c;具体编写看源代码就行&#xff0c;读起来也不复杂~ 谨慎&#xff…

windows文本绘制 TextOut、DrawText、CreateFont、SetTextColor、SetBkColor、SetBkMode

文本绘制 TextOut-将文字绘制在指定坐标位置 DrawText-在矩形区域绘制字符串 int DrawText(HDC hdc, //DC句柄LPCSTR lpString, //字符串int nCount, //字符串长度LPRECT lpRect, //绘制文字的矩形框UINT uFormat //绘制的方式,重点&#xff0c;花样繁多的关键点 );绘制文字样…

持续集成和上传源码

1.测试左移&#xff0c;测试右移 2.持续集成 是指通过自动化的方式&#xff0c;频繁多次将代码集成到主干。 快速发现错误 每完成一点更新&#xff0c;就集成到主干&#xff0c;可以快速发现错误&#xff0c;定位错误也比较容易。 防止分支大幅偏离主干 如果不是经常集成&…

nginx源码分析--双端列表

1.基本数据结构 struct ngx_queue_s {ngx_queue_t *prev;ngx_queue_t *next; };结构成员: ngx_queue_t *prev;前驱指针 ngx_queue_t *next;后继指针 2.操作函数--头结点 2.1基本函数 define ngx_queue_init(q) \(…

七牛云 vue 图片上传简单解说,js 上传文件图片

七牛云 vue 图片上传简单解说&#xff0c;js 上传文件图片 一、七牛云简介 首次使用七牛云存储进行项目的图片存储&#xff0c;整了一上午才整明白&#xff0c;这些官方的教程把明白人也给说糊涂了&#xff0c;文档很不规范。 七牛云有免费的使用额度&#xff0c;https://ww…

[附源码]SSM计算机毕业设计汽车租赁管理系统-JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Go学习之旅:包、变量和函数(DAY 1)

文章目录前引包、变量和函数1、包的概念和所用2、导出名或者导出函数3.1、函数参数声明方式&#xff08;一&#xff09;3.2、函数参数声明方式&#xff08;二&#xff09;4、函数返回值支持多值返回5、函数命名返回值6、变量声明7、变量的基础类型8、变量的默认值&#xff08;零…

pytorch案例代码-3

双向循环神经网络 双向循环神经网络在RNN/LSTM/GRU里都有。比如RNN cell&#xff0c;只是把h0和x1传入做线性变换产生h1继续传入同一个cell做线性变换&#xff0c;线性变换的W和b共享&#xff0c;沿着这个方向就把所有隐层和最后的输出算出来了。 那么其中的每个结点&#xff0…

android-apk解包打包

title: android-apk解包打包 categories: Android tags: [android, 加壳] date: 2022-09-28 10:29:51 comments: false mathjax: true toc: true android-apk解包打包, 以下所有操作都需要在配置好 java 环境下进行 前篇 android apk解包和打包 - https://blog.csdn.net/u0114…

(十五)Spring之面向切面编程AOP

文章目录基础环境AOP介绍AOP的七大术语切点表达式Spring的AOP的使用环境准备基于AspectJ的AOP注解式开发通知类型前置通知Before后置通知AfterReturning环绕通知Around异常通知AfterThrowing最终通知After关于JoinPoint切面的先后顺序通用切点表达式全注解式开发AOP基于XML配置…

9、前端笔记-CSS-CSS三大特性

三大特性&#xff1a;层叠性、继承性、优先级 1、层叠性&#xff08;覆盖性&#xff09; 给相同的选择器设置相同的样式&#xff0c;此时一个样式会覆盖&#xff08;层叠&#xff09;其他冲突的样式。 层叠性原则&#xff1a; 同一选择器&#xff0c;样式冲突&#xff0c;遵…

【SpringBoot】MVC配置解决跨域但仍然存在跨域

文章目录1. 跨域问题出现与解决1. 跨域问题出现与解决 检查SpringBoot中的MVC配置。 public void addCorsMappings(CorsRegistry registry) {//允许跨域访问资源定义registry.addMapping("/**")//(只允许本地的指定端口访问)允许所有.allowedOrigins("*")…

数据结构之线性表中的单链表【详解】

文章目录前言&#xff1a;一、单链表1.单链表和顺序表的优缺点2.单链表的概念和学习3.单链表的各个接口的实现&#xff08;详解每一步&#xff09;3.1.先铺垫一下大致的思路3.2.然后这边我们看一下我们大致要实现的函数有哪些3.3.接下来我们就开始实现这些代码&#xff0c;并且…

用信号量实现进程同步与互斥(含代码分析)

信号量简单的来说就是一个变量&#xff0c;代表着系统中互斥资源的数量&#xff0c;通常用原语来实现对信号量机制的操作。 一对原语&#xff1a;wait(S)也称为P操作&#xff0c;singnal(S)也称为V操作。S表示信号量 对于wait原语本身的内部逻辑代码如下&#xff08;这里以一…

黑苹果外接显示器最优解决方案

黑苹果无法外接显示器 黑苹果外接显示器解决方案 先给解决方案 电脑端 > 安装 PC端 Duet Display买个二手电视盒子40块钱左右&#xff0c;还带电源电视盒子 > 安装安卓端 Duet Display&#xff08;U盘安装就行&#xff09;电视盒子 > 用鼠标开启开发者模式双头USB&…