文章目录
一、搭建Zookeeper
官网地址:https://zookeeper.apache.org/
1、下载
官方下载地址:https://www.apache.org/dyn/closer.lua/zookeeper/zookeeper-3.8.0/apache-zookeeper-3.8.0-bin.tar.gz
2、安装启动
1> 解压
tar-zxvf apache-zookeeper-3.8.0-bin.tar.gz
2> 创建数据存放目录
cd apache-zookeeper-3.8.0-bin
mkdir data
3> 配置文件修改(conf目录下)
cd../conf
cp zoo_sample.cfg zoo.cfg
# 修改配置文件vi zoo.cfg
dataDir=/Users/xxx/software/zookeeper/apache-zookeeper-3.8.0-bin/data
4> 启动
cd../bin
./zkServer.sh start
5> 查看状态
./zkServer.sh status
这里Zookeeper是以standalone单机模式运行;
Zookeeper集群搭建参考文章:https://saint.blog.csdn.net/article/details/117109245。
二、Zookeeper分布式锁简述
Zookeeper实现排他锁的设计思路如下:
- zk用
/lock
节点作为分布式锁,当不同的客户端到zk竞争这把锁的时候,zk会按顺序给不同的客户端创建一个临时子节点,挂在作为分布式锁的节点下面。 - 假设第一个来到的客户端为A,第二个来到的是B,分布式锁节点下挂的第一个节点就是A(
/lock/_c_A
),B(/lock/_c_B
)紧跟着A,且B会监听着A的生命状态;- 这里B会先获取到/lock
路径下所有的节点,发现自己的锁节点(/lock/_c_B
)不在第一位,进而监听自己前一位的锁节点(/lock/_c_A
)。 - 当A释放锁后A节点会被删除;B监听到A被删除,B可以尝试获得分布式锁了。- 具体体现为:客户端B获取
/lock
下的所有子节点,并进行排序,判断排在最前面的是否为自己,如果自己的锁节点在第一位,代表取锁成功。- 如果还有C节点、D节点,他们都只会监听他们前一个节点,即:C监听B、D监听C。
三、curator客户端使用分布式锁
Curator提供的InterProcessMutex是分布式锁的实现。
acquire()
方法用于获取锁,
release()
方法用于释放锁。
1、curator概述
github: https://github.com/apache/curator
官方地址: https://curator.apache.org/
Apache Curator是Apache ZooKeeper(一种分布式协调服务)的Java/JVM客户端库。它包括一个高级API框架和实用程序,使Apache ZooKeeper的使用更加容易和可靠。
2、curator使用
引入curator的maven依赖,或者直接在curator源码中运行下列demo;
<dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.4.0</version><exclusions><exclusion><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>5.4.0</version></dependency><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.8.0</version><exclusions><exclusion><groupId>log4j</groupId><artifactId>log4j</artifactId></exclusion><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId></exclusion></exclusions></dependency>
importorg.apache.curator.framework.CuratorFramework;importorg.apache.curator.framework.CuratorFrameworkFactory;importorg.apache.curator.framework.recipes.locks.InterProcessMutex;importorg.apache.curator.retry.ExponentialBackoffRetry;/**
* @author Saint
*/publicclassLockTest{publicstaticvoidmain(String[] args){//重试策略,定义初试时间3s,重试3次ExponentialBackoffRetry exponentialBackoffRetry =newExponentialBackoffRetry(3000,3);//初始化客户端CuratorFramework client =CuratorFrameworkFactory.builder().connectString("127.0.0.1:2181").sessionTimeoutMs(3000).connectionTimeoutMs(3000).retryPolicy(exponentialBackoffRetry).build();// start()开始连接,没有此会报错
client.start();//利用zookeeper的类似于文件系统的特性进行加锁 第二个参数指定锁的路径InterProcessMutex interProcessMutex =newInterProcessMutex(client,"/lock");try{//加锁
interProcessMutex.acquire();System.out.println(Thread.currentThread().getName()+"获取锁成功");Thread.sleep(60_000);}catch(Exception e){
e.printStackTrace();}finally{try{//释放锁
interProcessMutex.release();System.out.println(Thread.currentThread().getName()+"释放锁成功");}catch(Exception e){
e.printStackTrace();}}}}
四、测试效果
在测试代码中,加锁成功之后线程会sleep 60s,这期间我们连上zookeeper可以看下效果;
1、几个常见命令
1)ls
ls命令:查看目录下的节点信息
ls[-s][-w][-R] path
- -s:显示节点详情,包括状态信息
- -w:添加一个watch监视器
- -R:列举出节点的级联节点
- path:显示某目录下节点/文件
2)stat
stat命令:查看节点状态。
stat[-w] path
- -w:添加watch
- path:查看某目录下节点的状态
3)get
get命令:获取节点/文件内容
get [-s][-w] path
- -s:查看节点数据以及节点状态信息
- -w:添加一个watch,节点数据变更时,会通知客户端(通知是一次性的)。
4)set
set命令:修改节点内容
set[-s][-v version] path data
- -s:更新节点数据并显示节点状态信息
- -v 指定数据版本号,如果指定的数据版本号和数据当前版本号不一致,则更新失败。
2、加锁解锁效果
1> 使用zkCli.sh 链接zookeeper
2> 加锁前后、释放锁后效果:
- 加锁后,/lock路径下会多一个临时节点;临时节点的内容为客户端IP
- 释放锁后,/lock路径的临时节点会被删除。
3、竞争锁效果
启动三次测试类 模拟多个并发的效果,idea中进行如下设置:
开启三次这个测试类之后,zookeeper的/lock路径下会有三个节点:
后启动的依赖于前一个启动的测试类释放分布式锁之后,才能获取到分布式锁。
版权归原作者 秃秃爱健身 所有, 如有侵权,请联系我们删除。