Zookeeper之分布式锁
来源:互联网 发布:linux中ping命令 编辑:程序博客网 时间:2024/06/09 05:42
Step 1:
private int threadId; private ZooKeeper zk = null; private String selfPath; private String waitPath; private String LOG_PREFIX_OF_THREAD; private static final int SESSION_TIMEOUT = 10000; private static final String GROUP_PATH = "/disLocks"; private static final String SUB_PATH = "/disLocks/sub"; private static final String CONNECTION_STRING = "192.168.*.*:2181"; private static final int THREAD_NUM = 10; //确保连接zk成功; private CountDownLatch connectedSemaphore = new CountDownLatch(1); //确保所有线程运行结束; private static final CountDownLatch threadSemaphore = new CountDownLatch(THREAD_NUM); private static final Logger LOG = LoggerFactory.getLogger(DistributedLock.class); public DistributedLock(int id) { this.threadId = id; LOG_PREFIX_OF_THREAD = "【第"+threadId+"个线程】"; }
Step 2:
获取锁
/** * 获取锁 * @return */ private void getLock() throws KeeperException, InterruptedException { selfPath = zk.create(SUB_PATH,null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); LOG.info(LOG_PREFIX_OF_THREAD+"创建锁路径:"+selfPath); if(checkMinPath()){ getLockSuccess(); } }
Step 3:
创建节点
/** * 创建节点 * @param path 节点path * @param data 初始数据内容 * @return */ public boolean createPath( String path, String data, boolean needWatch) throws KeeperException, InterruptedException { if(zk.exists(path, needWatch)==null){ LOG.info( LOG_PREFIX_OF_THREAD + "节点创建成功, Path: " + this.zk.create( path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT ) + ", content: " + data ); } return true; }
Step 4:
创建Zookeeper连接
/** * 创建ZK连接 * @param connectString ZK服务器地址列表 * @param sessionTimeout Session超时时间 */ public void createConnection( String connectString, int sessionTimeout ) throws IOException, InterruptedException { zk = new ZooKeeper( connectString, sessionTimeout, this); connectedSemaphore.await(); }
Step 5:
成功获取锁
/** * 获取锁成功 */ public void getLockSuccess() throws KeeperException, InterruptedException { if(zk.exists(this.selfPath,false) == null){ LOG.error(LOG_PREFIX_OF_THREAD+"本节点已不在了..."); return; } LOG.info(LOG_PREFIX_OF_THREAD + "获取锁成功,赶紧干活!"); Thread.sleep(2000); LOG.info(LOG_PREFIX_OF_THREAD + "删除本节点:"+selfPath); zk.delete(this.selfPath, -1); releaseConnection(); threadSemaphore.countDown(); }
Step 6:
关闭连接
/** * 关闭ZK连接 */ public void releaseConnection() { if ( this.zk !=null ) { try { this.zk.close(); } catch ( InterruptedException e ) {} } LOG.info(LOG_PREFIX_OF_THREAD + "释放连接"); }
Step 7:
检查自己是不是最小的节点
/** * 检查自己是不是最小的节点 * @return */ public boolean checkMinPath() throws KeeperException, InterruptedException { List<String> subNodes = zk.getChildren(GROUP_PATH, false); Collections.sort(subNodes); int index = subNodes.indexOf( selfPath.substring(GROUP_PATH.length()+1)); switch (index){ case -1:{ LOG.error(LOG_PREFIX_OF_THREAD+"本节点已不在了..."+selfPath); return false; } case 0:{ LOG.info(LOG_PREFIX_OF_THREAD+"子节点中,我果然是老大"+selfPath); return true; } default:{ this.waitPath = GROUP_PATH +"/"+ subNodes.get(index - 1); LOG.info(LOG_PREFIX_OF_THREAD+"获取子节点中,排在我前面的"+waitPath); try{ zk.getData(waitPath, true, new Stat()); return false; }catch(KeeperException e){ if(zk.exists(waitPath,false) == null){ LOG.info(LOG_PREFIX_OF_THREAD+"子节点中,排在我前面的"+waitPath+"已失踪,幸福来得太突然?"); return checkMinPath(); }else{ throw e; } } } } }
Step 8:
@Override public void process(WatchedEvent event) { if(event == null){ return; } Event.KeeperState keeperState = event.getState(); Event.EventType eventType = event.getType(); if ( Event.KeeperState.SyncConnected == keeperState) { if ( Event.EventType.None == eventType ) { LOG.info( LOG_PREFIX_OF_THREAD + "成功连接上ZK服务器" ); connectedSemaphore.countDown(); }else if (event.getType() == Event.EventType.NodeDeleted && event.getPath().equals(waitPath)) { LOG.info(LOG_PREFIX_OF_THREAD + "收到情报,排我前面的家伙已挂,我是不是可以出山了?"); try { if(checkMinPath()){ getLockSuccess(); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }else if ( Event.KeeperState.Disconnected == keeperState ) { LOG.info( LOG_PREFIX_OF_THREAD + "与ZK服务器断开连接" ); } else if ( Event.KeeperState.AuthFailed == keeperState ) { LOG.info( LOG_PREFIX_OF_THREAD + "权限检查失败" ); } else if ( Event.KeeperState.Expired == keeperState ) { LOG.info( LOG_PREFIX_OF_THREAD + "会话失效" ); } }
阅读全文
0 0
- Zookeeper之分布式锁
- Zookeeper实战之分布式锁
- Zookeeper框架Curator之分布式锁-yellowcong
- 分布式之ZooKeeper
- 分布式环境之-zookeeper
- zookeeper 分布式锁服务
- ZooKeeper示例 分布式锁
- zookeeper创建分布式锁
- zookeeper分布式锁DEMO
- zookeeper分布式锁
- zookeeper分布式锁(二)
- zookeeper分布式锁(三)
- zookeeper分布式锁(四)
- zookeeper分布式锁(五)
- zookeeper分布式锁(六)
- zookeeper分布式锁(七)
- zookeeper分布式锁(八)
- zookeeper分布式锁(九)
- 常见的SVN图标
- 输入输出挂模板
- latex入门1——5课笔记
- 18104 练习使用多case解题
- 【Java】java 遍历map对象的四种方式
- Zookeeper之分布式锁
- MATLAB学习笔记 学习总结归纳(第一周)
- 4. 编写函数,使字符串中尾部的*号不得多于n个
- Ubuntu用户ssh远程连接问题
- 【Java】一次Eclipse插件修改经历
- Windows and GPT FAQ
- return 在Java中作用
- spring4 + redis 零配置文件
- 调用windows打印机