美文网首页
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