2023-01-12
节点
4.1. 父类的设计
设计父类,提供连接ZooKeeper服务端的逻辑、节点操作的逻辑,所有方式实现的锁都需要继承自这个类。
package com.qianfeng.lock;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public abstract class ZkLockerBase implements Watcher {
/**
* 操作的锁名称
*/
protected String lockName;
/**
* ZooKeeper连接客户端
*/
private ZooKeeper zkCli = null;
/**
* 确保可以连接到ZooKeeper客户端
*/
private final CountDownLatch latch = new CountDownLatch(1);
/**
* 锁的根节点名称
*/
protected String rootNodeName = "/zk-lock";
/**
* 连接到预设的服务器
*/
public ZkLockerBase() {
this("qianfeng01:2181,qianfeng02:2181,qianfeng03:2181");
}
/**
* 连接到ZooKeeper的指定服务端
* @param connectString 连接字符串
*/
public ZkLockerBase(String connectString) {
try {
// 连接到ZooKeeper服务端
this.zkCli = new ZooKeeper(connectString, 5000, this);
// 等待连接成功的信号
this.latch.await();
// 创建根节点
createRootNode();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
public ZkLockerBase(String connectString, String lockName) {
this(connectString);
this.lockName = lockName;
}
/**
* 创建节点
* @param nodeName 创建的节点名称
* @param createMode 创建模式
* @return 创建成功的节点名称,如果创建失败,返回null
*/
public String createNode(String nodeName, CreateMode createMode) {
try {
// 创建节点,并返回创建成功之后的节点名称
return this.zkCli.create(nodeName, "".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);
} catch (KeeperException | InterruptedException ignored) {
}
return null;
}
/**
* 删除节点
* @param nodeName 删除的节点名称
* @return 删除的结果
*/
public boolean deleteNode(String nodeName) {
try {
// 删除节点
this.zkCli.delete(nodeName, -1);
return true;
} catch (InterruptedException | KeeperException ignored) {
}
return false;
}
/**
* 判断节点是否存在
* @param nodeName 节点的名字
* @return 是否存在
*/
public boolean exists(String nodeName) {
try {
Stat exists = zkCli.exists(nodeName, false);
return exists != null;
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
}
return false;
}
/**
* 创建根节点,存放所有的节点或者子节点实现的锁
*/
public void createRootNode() {
if (!exists(this.rootNodeName)) {
createNode(this.rootNodeName, CreateMode.CONTAINER);
}
}
public String getLockName() {
return this.rootNodeName + "/" + lockName;
}
public ZooKeeper getZkCli() {
return zkCli;
}
@Override
public void process(WatchedEvent event) {
switch (event.getType()) {
case None:
if (event.getState().equals(Event.KeeperState.SyncConnected)) {
// 说明连接到服务端成功
this.latch.countDown();
}
case NodeCreated:
processCreatedNode(event);
break;
case NodeDeleted:
processDeleteNode(event);
break;
case NodeChildrenChanged:
processChildernChange(event);
break;
}
}
// 创建节点回调
protected void processCreatedNode(WatchedEvent event) {}
// 删除节点回调
protected void processDeleteNode(WatchedEvent event) {}
// 子节点变更回调
protected void processChildernChange(WatchedEvent event) {}
}
锁接口的设计
提供所有的锁必须要实现的功能,制定锁的规范。
package com.qianfeng.lock;
/**
* ZooKeeper分布式锁通用接口
*
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public interface ZkLocker {
/**
* 上锁
*/
boolean lock();
/**
* 解锁
*/
boolean unlock();
/**
* 判断锁是否存在
* @return 是否存在
*/
boolean exists();
}
4.3. 节点实现的非阻塞性锁
package com.qianfeng.lock.nodeLock;
import com.qianfeng.lock.ZkLocker;
import com.qianfeng.lock.ZkLockerBase;
import org.apache.zookeeper.CreateMode;
/**
* @author 千锋大数据教研院 - 章鱼哥
* @company 北京千锋互联科技有限公司
*/
public class ZkLockerNodeNoneBlockingLocker extends ZkLockerBase implements ZkLocker {
public ZkLockerNodeNoneBlockingLocker(String connectString, String lockName) {
super(connectString, lockName);
}
public ZkLockerNodeNoneBlockingLocker(String lockName) {
super();
this.lockName = lockName;
}
/**
* 上锁
*/
@Override
public boolean lock() {
// 1. 拼接完整的节点路径
String lockNode = this.rootNodeName + "/" + lockName;
// 2. 创建锁
return createNode(lockNode, CreateMode.EPHEMERAL) != null;
}
/**
* 解锁
*/
@Override
public boolean unlock() {
// 1. 拼接完整的节点路径
String lockNode = this.rootNodeName + "/" + lockName;
// 2. 删除锁
return deleteNode(lockNode);
}
/**
* 判断锁是否存在
*
* @return 是否存在
*/
@Override
public boolean exists() {
// 1. 拼接完整的节点路径
String lockNode = this.rootNodeName + "/" + lockName;
// 2. 判断是否存在
return super.exists(lockNode);
}
}
上一篇:ZooKeeper实现分布式锁
下一篇:分布式锁的实现(二)
开班时间:2021-04-12(深圳)
开班盛况开班时间:2021-05-17(北京)
开班盛况开班时间:2021-03-22(杭州)
开班盛况开班时间:2021-04-26(北京)
开班盛况开班时间:2021-05-10(北京)
开班盛况开班时间:2021-02-22(北京)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2020-09-21(上海)
开班盛况开班时间:2021-07-12(北京)
预约报名开班时间:2019-07-22(北京)
开班盛况Copyright 2011-2023 北京千锋互联科技有限公司 .All Right 京ICP备12003911号-5 京公网安备 11010802035720号