zookeeper—分布式锁实现(笔记)
来源:互联网 发布:比特币交易网免费源码 编辑:程序博客网 时间:2024/06/04 18:59
使用Curator客户端实现
1.当有客户端访问锁资源时,先在zookeeper服务器上创建的锁节点下创建一个顺序节点,使用完锁资源删除创建的顺序节点。
2.当一个新的客户端想要访问锁资源时,先去zookeeper服务器锁节点下创建一个新节点,判断当前创建的节点编号是否为最小,若为最小表示当前只有本客户端想访问锁资源,然后访问资源便是。
3.若当前创建的节点编号不为最小,表示之前已有客户端在访问锁资源,需排队等待。所以监听比当前节点编号小一号的节点,若前一个节点被删除表示排在当前客户端前面的都执行完了锁资源,可以开始访问锁资源。
客户端操作接口:
public interface DistributedLock { //获取锁,若没有得到就等待 public void acquire() throws Exception; //获取锁,直到超时 public boolean acquire(long time,TimeUnit unit) throws Exception; //释放锁 public void realease() throws Exception;}
基础类(对zookeeper服务器操作的详细实现):
public class BaseDistributedLock { private final CuratorFramework client; private final String path; protected final String basePath; private final String lockName; private final static Integer MAX_RETRY_COUNT = 10; public BaseDistributedLock(CuratorFramework client, String path, String lockName) { this.client = client; this.basePath = path; this.path = path.concat("/").concat(lockName); this.lockName = lockName; } private void deleteOurpath(String ourPath) throws Exception { client.delete().guaranteed().deletingChildrenIfNeeded().forPath(ourPath); } private String createLockNode(CuratorFramework client, String path) throws Exception { return client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(path, null); } private boolean waitToLock(long startMillis, Long millisToWait, String ourPath) throws Exception { boolean haveTheLock = false; boolean doDelete = false; try { while (!haveTheLock){ List<String> children = getSortedChildren(); String sequenceNodeName = ourPath.substring(basePath.length() + 1); int ourIndex = children.indexOf(sequenceNodeName); if(ourIndex <0) { throw new NoNodeException("节点不存在: " + sequenceNodeName); } boolean isGetTheLock = ourIndex == 0; String psthToWatch = isGetTheLock ? null : children.get(ourIndex - 1); if(isGetTheLock) { haveTheLock = true; }else { String previousSequencePath = basePath.concat("/").concat(psthToWatch); final CountDownLatch latch = new CountDownLatch(1); try { client.getData().usingWatcher(new Watcher() { @Override public void process(WatchedEvent event) { if(event.getType() == EventType.NodeDeleted) { latch.countDown(); } } } ).forPath(previousSequencePath); if(millisToWait != null) { millisToWait -= (System.currentTimeMillis() - startMillis); startMillis = System.currentTimeMillis(); if(millisToWait <= 0) { doDelete = true; break; } latch.await(millisToWait, TimeUnit.MICROSECONDS); }else { latch.await(); } }catch(NoNodeException e) { e.printStackTrace(); } } } }catch(Exception e ) { doDelete = true; }finally{ if(doDelete) { deleteOurpath(ourPath); } } return haveTheLock; } private String getLockNodeNumber(String str, String lockName ) { int index = str.lastIndexOf(lockName); if(index >= 0) { index += lockName.length(); return index <= str.length() ? str.substring(index) : ""; } return str; } public List<String> getSortedChildren() throws Exception{ try { List<String> children = client.getChildren().forPath(basePath); Collections.sort ( children, new Comparator<String>() { public int compare(String lhs, String rhs) { return getLockNodeNumber(lhs, lockName).compareTo(getLockNodeNumber(rhs, lockName)); } } ); return children; }catch(NoNodeException e){ client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath(basePath); return getSortedChildren(); } } protected void releaseLock(String lockPath) throws Exception { deleteOurpath(lockPath); } protected String attemptLock(long time, TimeUnit unit) throws Exception { final long startMillis = System.currentTimeMillis(); final Long millisToWait = (unit != null) ? unit.toMillis(time) : null; String ourPath = null; boolean hasTheLock = false; boolean isDone = false; int retryCount = 0; while(!isDone) { isDone = true; try{ ourPath = createLockNode(client, path); hasTheLock = waitToLock(startMillis, millisToWait, ourPath); }catch(NoNodeException e) { if(retryCount++ < MAX_RETRY_COUNT) { isDone = false; }else { throw e; } } } if(hasTheLock) { return ourPath; } return null; }}
客户端的具体实现类:
public class SimpleDistributedLock extends BaseDistributedLock implements DistributedLock { //锁名称前缀 private static final String LOCK_NAME = "lock-"; private String ourLockPath; public SimpleDistributedLock(CuratorFramework client, String path) { super(client, path, LOCK_NAME); } private boolean internalLock(long time, TimeUnit unit) throws Exception{ ourLockPath = attemptLock(time, unit); return ourLockPath != null; } @Override public void acquire() throws Exception { if(!internalLock(-1,null)) { throw new IOException("连接丢失!" + basePath + "路径不能获取锁"); } } @Override public boolean acquire(long time, TimeUnit unit) throws Exception { return internalLock(time, unit); } @Override public void realease() throws Exception { releaseLock(ourLockPath); }}
测试类:
public static void main(String[] args) { RetryPolicy retry = new ExponentialBackoffRetry(1000, 3); CuratorFramework client1 = CuratorFrameworkFactory.newClient("192.168.0.3:2181", 5000, 5000, retry); CuratorFramework client2 = CuratorFrameworkFactory.newClient("192.168.0.3:2181", 5000, 5000, retry); client1.start(); client2.start(); SimpleDistributedLock lock1 = new SimpleDistributedLock(client1, "/Lock"); SimpleDistributedLock lock2 = new SimpleDistributedLock(client1, "/Lock"); try { lock1.acquire(); System.out.println("Client1 locked"); Thread client2Thr = new Thread(new Runnable() { @Override public void run() { try { lock2.acquire(); System.out.println("client2 locked"); lock2.realease(); System.out.println("client2 released"); }catch(Exception e) { e.printStackTrace(); } } }); client2Thr.start(); Thread.sleep(5000); lock1.realease(); System.out.println("client1 released"); client2Thr.join(); }catch(Exception e) { e.printStackTrace(); } }
console:
Client1 lockedclient1 releasedclient2 lockedclient2 released
阅读全文
0 0
- zookeeper—分布式锁实现(笔记)
- 分布式系统笔记:利用zookeeper实现分布式任务锁(Java)
- ZooKeeper实现分布式锁
- Zookeeper实现分布式锁
- ZooKeeper实现分布式锁
- ZooKeeper 实现分布式锁
- zookeeper实现分布式锁
- zookeeper实现分布式锁
- zookeeper实现分布式锁
- Zookeeper实现分布式锁
- Zookeeper实现分布式锁
- zookeeper实现分布式锁
- Zookeeper分布式锁实现
- Zookeeper 实现分布式锁
- zookeeper实现分布式锁
- Zookeeper分布式锁实现
- zookeeper实现分布式锁
- zookeeper实现分布式锁
- Spring MVC统一异常处理:HandlerExceptionResolver
- MyBatis插件及示例----打印每条SQL语句及其执行时间
- 如何在apk中添加上线用户的信息
- Linux如何用yum安装软件或服务
- APPCAN 电子签名设置
- zookeeper—分布式锁实现(笔记)
- IOS多线程开发其实很简单
- bzoj4917 [ lydsy6月月赛A题 ]
- opencv 采用多边形进行区域筛选
- android音乐播放器之歌词下载、处理、开始、同步
- ios NSoperation
- IE8,9中将event传到其他作用域会失效
- SpringMVC如何访问JSP
- python nonzero()函数的用法