Zookeeper java API的使用
zookeeper的安装
-
zookeeper 官网地址:https://zookeeper.apache.org
-
官网下载分为Linux与Windows版本,请选择系统相对应的release版本进行下载安装。
Linux环境安装
安装
-
选择相对应的下载链接,登录服务器后台,使用wget命令进行下载。
-
下载安装:
$ wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.14/zookeeper-3.4.14.tar.gz //下载
$ tar -zxvf zookeeper-3.4.14.tar.gz //解压
$ cd zookeeper-3.4.14/conf/ //进入zookeeper配置文件夹
$ cp zoo_sample.cfg zoo.cfg //复制zoo_sample.cfg文件并重新命名为zoo.cfg
$ cd ../bin/ //进入bin目录下
$ sh zkServer.sh start //启动zkServer
当服务端处于STARTED状态是,则zookeeper的服务端启动成功。
Windows环境安装
-
相遇对Linux系统,Windows系统则可以直接从官网下载安装包,解压后,则将 conf 目录下的 zoo_sample.cfg 文件,复制一份,重命名为 zoo.cfg。
-
在安装目录下面新建一个空的 data 文件夹和 log 文件夹。用于存储数据和日志信息。
-
修改 zoo.cfg 配置文件,将 dataDir=/tmp/zookeeper 修改成 zookeeper 安装目录所在的 data 文件夹,再添加一条添加数据日志的配置。注意:需要根据自己的安装实际路径修改
-
进入bin目录,双击 zkServer.cmd 启动程序。若窗口闪退,则排查zoo.cfg文件内修改的路径是否正确(本人是路径错误导致)
zookeeper的使用
- zookeeper安装成功后,下一步我们就要去用它,否则我们的安装则毫无意义,zookeeper的安装包的bin目录下有一个名为zkCli文件,Windows系统下名为:zkCli.cmd,Linux系统下名为:zkCli.sh,启动此程序,则可默认连接本机启动的zk服务端(可指定连接具体服务端)
zkCli.sh -server host:port # 指定连接节点,默认host=localhost,port=2181
- 当然,我们使用zookeeper肯定是希望应用到我们的项目中去,那这个时候使用zkCli肯定是无法做到的,这个时候,我们就需要在我们的程序中想办法去使用zookeeper的功能,对于java语言,这里记录两种最进本的入门级方法。(准备小本本儿记好)
一、ZK原生API
-
首先我们按照zookeeper的安装方式(此处以Windows为例),将zookeeper安装到本地。
-
创建Maven工程:
-
添加zookeeper依赖,zookeeper的依赖包可以单独在JDK下使用,所以使用zookeeper的原生API则直接添加zookeeper依赖包即可。
-
启动本地的zookeeper服务zkServer.cmd.
-
下面我们就来使用zookeeper的原生API创建我们的第一个链接zookeeper程序。
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import java.util.concurrent.CountDownLatch;
/**
* @ProjectName: zookeeper-demo
* @Package: com.mantou.zookeeper
* @ClassName: ZKConnectDemo
* @Author: MontyLee
* @Description: zookeeper原生API连接
* @Date: 2021/9/3 22:33
* @Version: 1.0
*/
public class ZKConnectDemo {
public static void main(String[] args) {
// 使用 CountDownLatch阻塞,等待连接
final CountDownLatch countDownLatch = new CountDownLatch(1);
try {
ZooKeeper zooKeeper = new ZooKeeper("127.0.0.1:2181", 5000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
if(Event.KeeperState.SyncConnected == watchedEvent.getState()){
// 收到服务端响应,则链接成功
countDownLatch.countDown();
}
}
});
countDownLatch.await();
System.out.println("Zookeeper 状态: "+zooKeeper.getState());
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 运行结果如下:
此时,zookeeper的连接状态为CONNECTED,表示已连接,接下来我们就可以对本地的zookeeper进行操作了(运行到此处,说明已经迈出了最重要的一步,恭喜你)。
Ⅰ、创建节点
- 经过我们的努力,我们已经连接上了zookeeper。话不多说,我们直接上代码来创建一个ZK节点。
// 创建节点
String createResp = zooKeeper.create(
"/mantou",
"".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL
);
- 上述create方法存在四个参数,意义如下:
- path:创建节点路径,只能单节点创建,无法直接创建子节点,如直接创建/mantou/montylee则会失败
- data:创建该节点下的数据。创建节点时,则可以给空
- acl:创建节点权限,ZooDefs.Ids.OPEN_ACL_UNSAFE则表示开放权限,Ids下包含其他各权限
- mode:创建节点模式,该枚举类内含有其他模式,此处我们创建临时节点。
- 创建成功后,我们可以通过本地zkCli.cmd客户端命令查询创建情况。
注意:启动客户端后执行创建程序,因创建为临时节点,先启动程序,再开启客户端则程序状态断开,新客户端开启不可见。也可以创建永久节点,避免出现此问题。
Ⅱ、查询节点
- 查询节点信息代码如下
Stat stat = zooKeeper.exists("/mantou",false);
- stat信息即为节点所有信息。
Ⅲ、修改节点
- 修改节点信息代码如下
Stat updateStat = zooKeeper.setData("/mantou","test".getBytes(), stat.getVersion());
- stat.getVersion()为查询的节点版本号(可视作乐观锁)
Ⅳ、删除节点
- 删除节点信息代码如下
zooKeeper.delete("/mantou",stat.getVersion());
- stat.getVersion()为查询的最新节点信息版本号(可视作乐观锁)
到此处,zookeeper的原生API操作方法已经简单的介绍完毕,剩下的就需要我们自己去探索,代码的世界处处充满惊喜,这些都在等待我们自己去发现。
二、Curator框架
Ⅰ、介绍
Curator 框架是一个高级 API,它极大地简化了 ZooKeeper 的使用。它添加了许多基于 ZooKeeper 构建的功能,并处理管理与 ZooKeeper 集群的连接和重试操作的复杂性。
Ⅱ、Curator依赖
- Curator框架的使用,要在Maven工程中添加其依赖,如下
- Curator 包含了几个包
curator-framework:对 zookeeper 的底层 api 的一些封装。
curator-client:提供一些客户端的操作,例如重试策略等。
curator-recipes:封装了一些高级特性,如:Cache 事件监听、选举、分布式锁、分布式计数器、分布式 Barrier 等。
Ⅲ、Curator操作
- 接下来,我们使用curator来操作我们本地的zookeeper。
- 首先,我们先连接本地zookeeper,其次是对zookeeper的各种操作,代码如下
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.data.Stat;
/**
* @ProjectName: zookeeper-demo
* @Package: com.mantou.zookeeper
* @ClassName: ZKCuratorDemo
* @Author: MontyLee
* @Description: Curator框架操作ZK
* @Date: 2021/9/3 23:47
* @Version: 1.0
*/
public class ZKCuratorDemo {
public static void main(String[] args) {
CuratorFramework curatorFramework= CuratorFrameworkFactory.
builder().connectString("127.0.0.1:2181").
sessionTimeoutMs(4000).retryPolicy(new
ExponentialBackoffRetry(1000,3))
.build();
curatorFramework.start();
Stat stat=new Stat();
// 具体操作
curatorFramework.close();
}
}
- 上述连接涉及到各个参数,下面对此进行解析
connectString:zk的server地址,多个server之间使用英文逗号分隔开
connectionTimeoutMs:连接超时时间,如上是30s,默认是15s
sessionTimeoutMs:会话超时时间,如上是50s,默认是60s
retryPolicy:失败重试策略ExponentialBackoffRetry:构造器含有三个参数 ExponentialBackoffRetry(int baseSleepTimeMs, int maxRetries, int maxSleepMs)
其他,查看org.apache.curator.RetryPolicy接口的实现类
start()会阻塞到会话创建成功为止。
①创建节点
- 创建一个空节点
client.create().forPath(path);
- 创建一个包含内容的节点
client.create().forPath(path,"内容XXX".getBytes());
- 创建临时节点,并递归创建父节点
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path);
注意: 递归创建父节点时,父节点为持久节点。
②删除节点
- 删除一个子节点
client.delete().forPath(path);
- 删除节点并递归删除其子节点
client.delete().deletingChildrenIfNeeded().forPath(path);
- 指定版本进行删除
client.delete().withVersion(1).forPath(path);
- 强制保证删除一个节点
client.delete().guaranteed().forPath(path);
③查询节点
- 普通查询
client.getData().forPath(path);
- 包含状态查询
Stat stat = new Stat();
client.getData().storingStatIn(stat()).forPath(path);
④更新节点
- 普通更新
client.setData().forPath(path,"更新内容XXX".getBytes());
- 指定某一版本更新
client.setData().withVersion(1).forPath(path);
完整程序:
更多关于zookeeper和Curator的使用可以参照官方文档