使用Zookeeper\curator实现分布式锁

  • 相对于使用redis,用zk实现分布式锁有着天生的优势,具体的原因之后有机会再记录,直接进入如何使用。
  1. 构建InterProcessLock
    @Bean
    public InterProcessLock interProcessLock() {
        CuratorFramework curatorFramework = getZkClient(host);
        curatorFramework.start();
        InterProcessLock interProcessLock = new InterProcessMutex(curatorFramework,
                zkPathEnvironment);
        return interProcessLock;
    }
  • 此处使用InterProcessLock的InterProcessMutex可重入锁实现。
  1. 业务逻辑加锁
    public void syncMemberFromGitlabJob() throws Exception {
        System.out.println("=======================定时同步任务开始=======================");
        //加锁
        if(!interProcessLock.acquire(1, TimeUnit.MILLISECONDS)){
            throw new RuntimeException("排他锁获取失败");
        }
        System.out.println("=======================同步任务加zk锁成功=======================");

        try {

            //逻辑
            Thread.sleep(20000);

            System.out.println("=======================定时同步任务完成=======================");
        }catch (Exception e){
            System.out.println("=======================同步时出现错误,错误为:" + e.getMessage());
        }finally {
            //释放锁
            interProcessLock.release();
            System.out.println("=======================同步任务释放zk锁成功=======================");
        }

    }
  • 执行中使用interProcessLock.acquire()尝试上锁,acquire()有两种构建方法,源码为:
    /**
     * Acquire the mutex - blocking until it's available. Each call to acquire must be balanced by a call
     * to {@link #release()}
     *
     * @throws Exception ZK errors, connection interruptions
     */
    public void acquire() throws Exception;

    /**
     * Acquire the mutex - blocks until it's available or the given time expires. Each call to acquire that returns true must be balanced by a call
     * to {@link #release()}
     *
     * @param time time to wait
     * @param unit time unit
     * @return true if the mutex was acquired, false if not
     * @throws Exception ZK errors, connection interruptions
     */
    public boolean acquire(long time, TimeUnit unit) throws Exception;

两种构建方法分别使用不同情况,两者都会尝试创建节点,不带构建参数的acquire方法若无法创建会阻塞主进程直至可创建或异常,带时间构造参数的acquire方法则会在指定时间段内尝试,如果在这段时间内没有成功创建,则会返回false,反之为true。各位可以根据自己的需求进行选择。

  1. 测试效果
  • 服务1先进行调用,查看zk中新增了临时节点
    在这里插入图片描述

  • 服务2后进行调用
    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值