基于Zookeeper使用InterProcessMutex排他锁

1、导入相关依赖

<dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-recipes</artifactId>
            <version>5.2.0</version>
        </dependency>

2、zookeeper的相关配置

# zk配置
curator:
  retryCount: 5      #重试次数
  baseSleepTimeMs: 1000   #重试间隔时间
  connectString: 127.0.0.1:2181    # zk地址
  sessionTimeoutMs: 60000          #session超时时间
  connectionTimeoutMs: 5000         #连接超时时间
package com.cxb.springboot.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * @Classname WrapperZk
 * @Description TODO
 * @Date 2023/3/28 21:57
 * @Created by Administrator
 */
@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZk {

    private int retryCount;

    private int elapsedTimeMs;

    private String connectString;

    private int sessionTimeoutMs;

    private int connectionTimeoutMs;

    private int baseSleepTimeMs;
}
package com.cxb.springboot.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

/**
 * @Classname ZkConfiguration
 * @Description TODO
 * @Date 2023/3/28 21:57
 * @Created by Administrator
 */
@Configuration
@Slf4j
public class ZkConfiguration {

    @Resource
    WrapperZk wrapperZk;

    /**
     * 其中RetryPolicy为重试策略,第一个参数为baseSleepTimeMs初始的sleep时间,
     * 用于计算之后的每次重试的sleep时间。第二个参数为maxRetries,最大重试次数。
     * @return
     */
    @Bean(initMethod = "start")
    public CuratorFramework curatorFramework() {
        RetryPolicy retrYPolicy = new ExponentialBackoffRetry(wrapperZk.getBaseSleepTimeMs(),
                wrapperZk.getRetryCount());
        CuratorFramework client = CuratorFrameworkFactory
                .newClient(wrapperZk.getConnectString(), retrYPolicy);
        log.info("zk curator初始化完成...");
        return client;
    }
}

3、使用多线程模拟抢占锁

package com.cxb.springboot.controller;

import com.cxb.springboot.config.ZkConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Classname MicroController
 * @Description TODO
 * @Date 2023/3/28 22:03
 * @Created by Administrator
 */
@Controller
@RequestMapping("/zk")
@Slf4j
public class MicroController {

    private final static String PATH = "/rootLock";

    @Autowired
    ZkConfiguration zkConfiguration;

    /**
     * 这里我用的是最常用的可重入排他锁,也是公平锁(InterProcessMutex)
     * InterProcessMutex:分布式可重入排它锁
     * InterProcessSemaphoreMutex:分布式排它锁
     * InterProcessReadWriteLock:分布式读写锁
     * InterProcessMultiLock:将多个锁作为单个实体管理的容器
     * @return
     * @throws Exception
     */
    @RequestMapping("/lock")
    @ResponseBody
    public String getLock1() throws Exception {
        InterProcessMutex lock = new InterProcessMutex(zkConfiguration.curatorFramework(), PATH);
        for (int i = 0; i < 30; i++) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        log.info(Thread.currentThread().getName() + "尝试获取锁....");
                        lock.acquire();
                        log.info(Thread.currentThread().getName() + "获取锁成功....");
                        log.info(Thread.currentThread().getName() + "开始执行业务逻辑....");
                        Thread.sleep(10000);
                        lock.release();
                        log.info(Thread.currentThread().getName() + "释放锁成功....");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
            thread.start();
        }
        return "execute success";
    }
}

调用接口: http://localhost:8081/zk/lock 然后使用zookeeper的可视化工具查看当前节点的信息。

 等待任务执行完成之后,所有的节点信息都会被移除

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值