所声调剂后的分布式锁算法流程如下:
- 客户端连接zookeeper,并在/lock下创建 临时的 且 有序的 子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以词攀类推。
- 客户端获取/lock下的子节点列表,断定本身创建的子节点是否为当缁び节点列表中 序号最小 的子节点,如不雅是则认为获得锁,不然 监听刚好在本身之前一位的子节点删除消息 ,获得子节点变革通知后反复此步调直至获得锁;
- 履行营业代码;
- 完成营业流程后,删除对应的子节点释放锁。
- <dependency>
- <groupId>org.apache.curator</groupId>
- <artifactId>curator-recipes</artifactId>
- <version>4.0.0</version>
- </dependency>
然后就可以用啦!代码如下:
- public static void main(String[] args) throws Exception {
- //创建zookeeper的客户端
- RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
- CuratorFramework client = CuratorFrameworkFactory.newClient("10.21.41.181:2181,10.21.42.47:2181,10.21.49.252:2181", retryPolicy);
- client.start();
- //创建分布式锁, 锁空间的根节点路径为/curator/lock
- InterProcessMutex mutex = new InterProcessMutex(client, "/curator/lock");
- mutex.acquire();
- //获得了锁, 进行营业流程
- System.out.println("Enter mutex");
- //完成营业流程, 释放锁
- mutex.release();
- //封闭客户端
- client.close();
- }
可以看到关键的核心操作就只有mutex.acquire()和mutex.release(),的确太便利了!
下面来分析下获取锁的源码实现。acquire的办法如下:
实现分布式锁今朝有三种风行筹划,分别为基于数据库、Redis、Zookeeper的筹划,个中前两种筹划收集上有很多材料可以参考,本文不做展开。我们来看下应用Zookeeper若何实现分布式锁。
- /*
- * 获取锁,当锁被占用时会壅塞等待,这个操作支撑同线程的可重入(也就是反复获取锁),acquire的次数须要与release的次数雷同。
- * @throws Exception ZK errors, connection interruptions
- */
- @Override
- public void acquire() throws Exception
- {
- if ( !internalLock(-1, null) )
- {
- throw new IOException("Lost connection while trying to acquire lock: " + basePath);
- }
- }
这里有个处所须要留意,当与zookeeper通信存在异常时,acquire会直接抛出异常,须要应用者自身做重试策略。代码中调用了internalLock(-1, null),参数注解在锁被占用时永远壅塞等待。internalLock的代码如下:
- private boolean internalLock(long time, TimeUnit unit) throws Exception
推荐阅读
沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散!“计算机法度榜样可以在给定某种类其余义务 T 和机能度量 P 下进修经验 E ,如不雅其在义务 T 中的机能正好可以用 P>>>详细阅读
本文标题:基于Zookeeper的分布式锁
地址:http://www.17bianji.com/lsqh/38128.html
1/2 1