美文网首页
zookeeper实现分布式锁的优化

zookeeper实现分布式锁的优化

作者: 守住阳光 | 来源:发表于2018-10-13 14:15 被阅读0次

        上篇文章讲到了如何利用zookeeper实现分布式锁,并提供了代码示例。但是前面的解决方案存在如下缺点:

        1、客户端接受了很多与自己无关的事件通知。因为一个进程解锁后会通知所有后面正在监听的进程,这是没有必要的;

        2、由于上面的过多的事件监听和通知,导致并发量大时,性能较差。

        典型的羊群效应:

        1、巨大的服务器性能损耗;

        2、网络冲击;

        3、可能造成宕机。

一、改进后的数据结构和流程

        改进后的方案使用临时顺序节点,具体流程如下:

改进后的实现流程

二、实现代码示例

public class ZookeeperImproveLock extends AbstractLock{

        //当前请求的节点

        private String currentPath ;

        //当前请求节点的前一个节点

        private String beforePath ;

        private CountDownLatch cdl =null;

        /**

        * 解锁即删除当前节点

        */

        @Override

        public void unLock() {

                zkClient.delete(currentPath);

                 currentPath =null;

        }

        /**

        * 如果创建临时节点成表示获取锁成功

        */

        @Override

        protected boolean tryLock() {

                try{

                        //如果currentPath为空则为第一次尝试加锁,第一次加锁赋值currentPath

                        if(currentPath==null||currentPath.length()<=0){

                               //创建一个临时顺序节点

                                currentPath = zkClient.createEphemeralSequential(path, "lock");

                        }

                        //获取所有临时顺序节点并排序,临时节点为自增长的字符串,如00001;

                        List<String> children = zkClient.getChildren(path);

                        //进行排序

                        Collections.sort(children);

                        if(currentPath.equals(path+children.get(0))){

                                //如果当前节点在所有节点中排名第一则获取成功

                                return true;

                        }else{

                                //如果当前节点在所有节点中排名不是第一,则获取当前节点的前面的节点名称并赋值

                                int wz = Collections.binarySearch(children, currentPath.substring(5));

                                beforePath = path + children.get(wz -1);

                                return false;

                        }

                    }catch(Exception e){

                           return false ;

                    }

        }

        @Override

        protected void waitForLock() {

                IZkDataListener listener = new IZkDataListener(){

                        @Override

                        public void handleDataChange(String dataPath, Object data) throws Exception {

                        }

                        @Override

                        public void handleDataDeleted(String dataPath) throws Exception {

                                    //监听临时节点删除事件

                                    if(cdl!=null){

                                        cdl.countDown();

                                    }

                        }

            };

            //订阅节点改变事件

            zkClient.subscribeDataChanges(beforePath, listener);

            if(zkClient.exists(beforePath)){

                cdl = new CountDownLatch(1);

                try {

                    cdl.await();

                } catch (InterruptedException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

                }

           }

            zkClient.unsubscribeDataChanges(beforePath, listener);

       }

}

相关文章

网友评论

      本文标题:zookeeper实现分布式锁的优化

      本文链接:https://www.haomeiwen.com/subject/pohoaftx.html