Curator分散式鎖注意事項
阿新 • • 發佈:2019-01-22
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()); } } } }