前置文章:
一、ZooKeeper基础-数据结构、服务端/客户端常用命令
二、ZooKeeper Java API基本操作-建立连接&增删改查
三、ZooKeeper Java API操作-Curator Watch事件监听
零、本文纲要
一、分布式锁
二、ZooKeeper实现分布式锁
三、分布式锁的代码实现
一、分布式锁
- 单机
单机应用同一个JVM,使用synchronized或者Lock来解决多线程代码同步问题。 - 分布式
跨JVM,synchronized或者Lock无法实现。
分布式锁——解决跨机器进程之间的数据同步问题。
二、ZooKeeper实现分布式锁
- ZooKeeper分布式锁原理
①客户端获取锁:在/lock节点下创建 临时顺序 节点;
②创建的子节点序号最小的客户端得到锁:获取/lock下所有子节点,节点最小的客户端得到锁;
③未得到锁的客户端对比自己小的最近节点注册监听,监听删除事件;
④得到锁的客户端操作完/宕机超时,删除临时节点,Watcher收到通知,节点最小的节点获取到锁进行操作。
- Curator提供的五种类型锁
①InterProcessSemaphoreMutex:分布式排它锁(非可重入)
②InterProcessMutex:分布式可重入排它锁
③InternalInterProcessMutex:分布式读写锁
④InterProcessMultiLock:将多个锁作为单个实体管理的容器
⑤InterProcessSemaphoreV2:共享信号量
三、分布式锁的代码实现
- 使用InterProcessLock
private InterProcessLock lock;
new InterProcessMutex(CuratorFramework client, String path);//path为锁节点路径
//重试策略
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000,10);
//第二种方式
CuratorFramework client= CuratorFrameworkFactory.builder()
.connectString("192.168.253.128:2181")
.sessionTimeoutMs(60 * 1000)
.connectionTimeoutMs(15 * 1000)
.retryPolicy(retryPolicy).build();
//开启连接
client.start();
InterProcessLock lock = new InterProcessMutex(client,"/lock");//此处为方便阅读把InterProcessLock类型写在代码块内部,实际使用应该作为成员变量
- 获取锁/释放锁
lock.acquire(long time, TimeUnit unit);//获取锁
lock.release();//释放锁
try {
//获取锁
lock.acquire(3, TimeUnit.SECONDS);
if (tickets > 0){
System.out.println(Thread.currentThread() + ":" + tickets);
tickets--;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放锁
try {
lock.release();
} catch (Exception e) {
e.printStackTrace();
}
}
四、结尾
以上即为ZooKeeper 分布式锁的简单介绍,感谢阅读。