1. 程式人生 > >Curator分散式鎖注意事項

Curator分散式鎖注意事項

package com.example.demo.util;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.apache.curator.framework.recipes.locks.LockInternalsDriver;
import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 分散式鎖
 * 1.加鎖操作會生成zookeeper順序節點,並且節點順序每次遞增,例如:<path>0000000000,<path>0000000001
 * 2.這個序號值是永久遞增的,當超過int的最大值 (2147483647)時,生成的臨時順序節點為<path>-2147483647
 * 3.通過設定 threshold 設定閥值(百分比),當序號大於閥值時,嘗試刪除父節點,
 *   當再有加鎖操作時,序號會從<path>0000000000重新開始
 * 注意: 刪除父節點時,如果含有子節點,則會刪除失敗,也就是說當業務的併發量為1時,才會刪除
 * Created by lp on 2017/7/26.
 */
public class DistributedLock extends InterProcessMutex {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    public static double threshold = 0.8;

    private CuratorFramework client;

    public DistributedLock(CuratorFramework client, String path) {
        super(client, path);
        this.client = client;
    }

    public DistributedLock(CuratorFramework client, String path, LockInternalsDriver driver) {
        super(client, path, driver);
    }

    @Override
    public void release() throws Exception {
        // 鎖的當前節點
        String lockPath = super.getLockPath();
        Double counterMax =  (new Double(Integer.MAX_VALUE) * threshold);
//        Double counterMax =  3d;

        Double counterCurrent = new Double(lockPath.substring(lockPath.length()-10));
        String parentPath = lockPath.substring(0,lockPath.lastIndexOf("/"));
        super.release();
        if(counterCurrent >= counterMax){
            logger.info("臨時鎖節點[ " + lockPath + " ]超過閥值[ " + counterMax.intValue() +" ],刪除父節點[ " + parentPath + " ]");
            try{
                this.client.delete().forPath(parentPath);
            }catch (KeeperException.NotEmptyException e){
                logger.error(e.getMessage());
            }
        }
    }
}