简单的zookeeper分布式锁

1.什么是分布式锁,为什么需要分布式锁?

答:随着互联网的发展,单机项目已经远远不能满足市场的需求,许多项目开始使用基于springCloud和dubbo的分布式解决方案,但是由于许多项目采用集群方案部署,导致jvm自带的synchronized、Lock等不能满足项目的需求,例如当实现商品秒杀时,前端的高并发请求会同时访问不同的服务器,当你使用synchronized或者Lock的时候,只能锁定本台服务器的某个方法或代码块。这时候分布式锁就显得尤为重要。

2.分布式锁有哪几种结局方案?

答:基于zookeeper解决方案、基于redis解决方案、基于数据库的解决方案

3.zookeeper方案是如何解决的,原理是什么?

答:zookeeper官网数据结构图

简单的zookeeper分布式锁_第1张图片
image

这个是官网的zookeeper数据图,从图中就可以看出zookeeper是一种树形的数据结构,它存贮数据的地方就是它的节点,zookeeper分布式锁也是基于此来做的,当某个程序获得锁之后,创建一个临时节点,其它并发请求获取锁的时候,先判断一下,该节点存不存在,若存在则等待并监听,不存在,创建临时节点获取锁。当程序运行完断开连接,或者删除临时节点来进行锁释放。

4.zookeeper如何使用代码来实现分布式锁?

答:pom.xml文件

        
        
        com.101tec
        zkclient
        0.11
        

接口

/**
 * @author oumiga
 */
public interface ZookeeperLock {
    /**
     * 获取锁
     */
    public void lock();

    /**
     * 释放锁
     */
    public void closeLock();
}

抽象类

import org.I0Itec.zkclient.ZkClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

/**
 * @author oumiga
 */
public abstract class AbstractZookLock implements ZookeeperLock {

    @Value("${zookeeper.LockIp}")
    protected String zookeeperIp;

    protected ZkClient zkClient;

    protected String elementName = "/lock";

    protected CountDownLatch countDownLatch;
    @Override
    public void lock() {
        boolean lock = tryLock();
        if(!lock){
            waitLock();
            lock();
        }
    }

    /**
     * 关闭连接,释放锁
     */
    @Override
    public void closeLock() {
        if(Objects.nonNull(zkClient)){
            zkClient.close();
        }
    }

    public abstract boolean tryLock();

    public abstract void waitLock();

    /**
     * 获取Zkclient对象
     * @return
     */
    public ZkClient getZkClient(){
        if(zkClient == null){
            if(StringUtils.isEmpty(zookeeperIp)){
                new ZkClient(zookeeperIp);
                return zkClient;
            }
            zkClient = new ZkClient("127.0.0.1");
            return zkClient;
        }
        return zkClient;
    }
}

抽象实现类

import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;

/**
 * @author oumiga
 */
public class ZookLockImpl extends AbstractZookLock {


    /**
     * 尝试获取锁
     * @return
     */
    @Override
    public boolean tryLock() {
        try{
            ZkClient zkClient = getZkClient();
            if(!zkClient.exists(elementName)){
                return false;
            }
            zkClient.createEphemeral(elementName);
            countDownLatch = new CountDownLatch(1);
            return true;
        }catch(Exception e){
            return false;
        }

    }

    /**
     * 等待锁释放
     */
    @Override
    public void waitLock() {
        ZkClient zkClient = getZkClient();
        IZkDataListener iZkDataListener = new IZkDataListener() {
            //监听数据的改变
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            //监听数据的删除
            @Override
            public void handleDataDeleted(String s) throws Exception {
                if(Objects.nonNull(countDownLatch)){
                    countDownLatch.countDown();
                }
            }
        };
        //监听节点
        zkClient.subscribeDataChanges(elementName,iZkDataListener);
        if(zkClient.exists(elementName)){
            try {
                countDownLatch.await();

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        zkClient.unsubscribeDataChanges(elementName,iZkDataListener);
    }
}

工具使用类

/**
 * @author oumiga
 */
public  class zookLockUtils {
    private static ZookeeperLock zookeeperLock = new ZookLockImpl();

    /**
     * 获取锁
     */
    public static void lock(){
        zookeeperLock.lock();
    }

    /**
     * 释放锁
     */
    public static void closeLock(){
        zookeeperLock.closeLock();
    }
}

你可能感兴趣的:(简单的zookeeper分布式锁)