文章目录
-
- 前言
- 需要考虑的细节
-
-
- 如果出现异常,没有删掉结点,进而这个锁永远无法释放,怎么办?
- 如果在Finally之前服务器宕机了怎么办?
- 如果事件监听机制会通知上轮取锁失败者,导致羊群效应怎么办?
-
- 基于Curator实现Zookeeper实战
前言
Zookeeper实现分布式锁的核心在于
独占性
,即当有人创建过某结点,那么再次创建的时候,就不可创建,我们可根据是否能成功创建来实现
加锁
操作,而如何释放锁呢?走完流程删掉这个结点就可以了。
zk-客户端连接zk实现,如果重复创建会提示‘
Node already exists: /lock
’,在并发情况下,只有一个请求是可以创建成功的,其他的请求会通过
get -w
监听该节点
[zk: localhost:2181(CONNECTED) 20] create /lock
Created /lock
[zk: localhost:2181(CONNECTED) 21] create /lock
Node already exists: /lock
整体思路比较简单,但是要考虑很多细节。
需要考虑的细节
如果出现异常,没有删掉结点,进而这个锁永远无法释放,怎么办?
保证其释放了就行,例如在Java中可以使用
try catch
中的
finally
去保证其进行删除结点的操作
如果在Finally之前服务器宕机了怎么办?
这样Finally就失效了,此时我们想到了Zookeeper中的临时结点,让其自动释放
如果事件监听机制会通知上轮取锁失败者,导致羊群效应怎么办?
可以使用临时顺序节点,为所有的获取锁请求创建临时顺序结点,这样每个请求创建的临时顺序结点类似于lock0000001、lock0000002…这样的形式,每次编号最小的获取结点,且编号次小的会对编号最小的顺序结点进行监听,也就是2监听1,3监听2这种… ,2监听到1释放了,2就会拿锁,这样就避免了羊群效应。
基于Curator实现Zookeeper实战
Curator是Zookeeper客户端工具,也就是说我们可以在自己的系统中集成Curator,并借助它对Zookeeper进行操作。
引入Curator依赖
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.3.0</version>
</dependency>