Curator分布式锁注意事项

本文介绍了一种基于Curator框架的分布式锁优化方案,通过设置阈值,在达到int最大值时,将计数器归零,确保锁节点的正常生成。文章详细解释了zookeeper中顺序节点的工作原理,并提供了具体的实现代码。

Curator分布式锁注意事项

  1. zookeeper 分布式锁的实现以及原理,详见zookeeper 分布式锁的实现
  2. 顺序节点值是永久递增的,当超过int的最大值 (2147483647)时,生成的临时顺序节点为<path>-2147483647
    官方的说明:
    Sequence Nodes -- Unique Naming
    When creating a znode you can also request that ZooKeeper append a monotonically increasing counter to the end of path. This counter is unique to the parent znode. The counter has a format of %010d -- that is 10 digits with 0 (zero) padding (the counter is formatted in this way to simplify sorting), i.e. "<path>0000000001". See Queue Recipe for an example use of this feature. Note: the counter used to store the next sequence number is a signed int (4bytes) maintained by the parent node, the counter will overflow when incremented beyond 2147483647 (resulting in a name "<path>-2147483647").
  3. 解决思路,就是将顺序节点的计数器归0

具体代码如下:

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());
            }
        }
    }
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值