分布式锁系列 —— zookeeper同级节点唯一性实现
前言
目前社会盛行微服务架构,因此导致对于事务场景存在跨服务的场景,分布式锁就是对于各服务之间同步访问统一资源的控制方式,本文通过对zookeeper的同级节点唯一性实现分布式锁机制原理
利用 zookeeper 的同级节点的唯一性特性,在获取锁时,所有的请求试图通过API中的zk.create()接口,在指定路径节点下创建临时子节点,最终只有一个请求能创建节点成功,那么这个创建节点的请求就相当于获得锁。同时,所有没有获取到锁的请求可以在其它节点上创建一个子节点设置 watcher 监听事件,一旦目录节点的状态发生变化,Watcher 对象的 process 方法就会被调用。重新去争取锁。
简单实现(使用curator 工具包封装的API实现)
1.引入库
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.1.0</version>
</dependency>
2. curator 工具包锁类型
1、InterProcessMutex:分布式可重入排他锁
2、InterProcessSemaphoreMutex:分布式排他锁
3、InterProcessReadWriteLock:分布式读写锁
3.测试代码
package com.wealth.product.service.info;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.locks.InterProcessSemaphoreMutex;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* @author Jian
* @Description 测试curator 工具包
* @createTime 2021-05-28
*/
public class TestZKLock {
public static void main(String[] args){
// 获取zk客户端
CuratorFramework curatorFramework = getCF();
String lockPath = "/zkLock";
InterProcessSemaphoreMutex lock = new InterProcessSemaphoreMutex(curatorFramework, lockPath);
//模拟10个线程抢锁
for (int i = 0; i < 10; i++) {
new Thread(new ZKThread(i, lock)).start();
}
}
/**
* 初始化 zk客户端
* @return
*/
private static CuratorFramework getCF() {
String zkServerAddress = "127.0.0.1:2181";
ExponentialBackoffRetry retryPolicy = new ExponentialBackoffRetry(1000, 3, 5000);
CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
.connectString(zkServerAddress)
.sessionTimeoutMs(5000)
.connectionTimeoutMs(5000)
.retryPolicy(retryPolicy)
.build();
curatorFramework.start();
return curatorFramework;
}
}
/**
* 线程类 - 实现Runbable
*/
class ZKThread implements Runnable {
private Integer no;
private InterProcessSemaphoreMutex ipsmLock;
public ZKThread(Integer no, InterProcessSemaphoreMutex ipsmLock) {
this.no = no;
this.ipsmLock = ipsmLock;
}
@Override
public void run() {
try {
ipsmLock.acquire();
System.out.println(no+" : ------------获得锁");
//等到1秒后释放锁
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
ipsmLock.release();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
学习来源:https://www.runoob.com/w3cnote/zookeeper-locks.html