zookeeper分布式锁

2022-09-29 12:23:57 浏览数 (1)

场景

“分布式锁”是用来解决分布式应用中“并发冲突”的一种常用手段,实现方式一般有基于zookeeper及基于redis二种

使用基于zookeeper的分布式锁

所需组件:

  • zookeeper服务
  • Curator 客户端

启动zookeeper

一般是集群部署,启动zookeeper服务端。

java 代码

Curator 是一个 基于 zookeeper服务 的客户端工具

curator提供了InterProcessMutex 这样一个api。除了分布式锁之外,还提供了leader选举、分布式队列等常用的功能。 InterProcessMutex:分布式可重入排它锁 InterProcessSemaphoreMutex:分布式排它锁 InterProcessReadWriteLock:分布式读写锁

引入依赖:

代码语言:javascript复制
<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>

初始化会话连接:

代码语言:javascript复制
@Bean
CuratorFramework CuratorFramework() {
    CuratorFramework curatorFramework = CuratorFrameworkFactory.builder()
            .connectString("192.168.1.111:2181")
            .sessionTimeoutMs(15000)
            .connectionTimeoutMs(20000)
            .retryPolicy(new ExponentialBackoffRetry(1000, 10))
            .build();

    //打开连接
    curatorFramework.start();
    //是否成功建立连接,true :建立, false:没有建立
    System.out.println("是否打开:" curatorFramework.isStarted());
    return curatorFramework;

主要方法:

InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/LOCK_LOCK_2"); lock.acquire();//抢占分布式锁资源(阻塞的) lock.release();

示例:

代码语言:javascript复制
// 引入Zookeeper实现分布式锁 ,curator客户端
    private synchronized String impl08() throws Exception {
        System.out.println("基于临时有序节点来实现的分布式锁 的实现");
        // 基于临时有序节点来实现的分布式锁.
        InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/LOCK_LOCK_2");
        try {
            lock.acquire();//抢占分布式锁资源(阻塞的)

            //----------------------
            String res = "";
            String stockStr = stringRedisTemplate.opsForValue().get("stock");
            if (StringUtils.isEmpty(stockStr)) return "库存为空";
            int stock = Integer.parseInt(stockStr);
            if (stock > 0) {
                int newStock = stock - 1;
                stringRedisTemplate.opsForValue().set("stock", newStock   "");
                res = String.format("扣减成功 from %s to %s n", stock, newStock);
                System.out.println(res);
            } else {
                res = String.format("扣减失败 from %s n", stock);
                System.out.println(res);
            }
            return res;
        } finally {
            // 完事后释放 锁
            lock.release();
        }
    }

0 人点赞