iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >ZooKeeper分布式锁的实现方式
  • 872
分享到

ZooKeeper分布式锁的实现方式

2023-06-20 12:06:46 872人浏览 八月长安
摘要

本篇内容介绍了“ZooKeeper分布式锁的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录一、分布式锁方案比较二、ZooKeep

本篇内容介绍了“ZooKeeper分布式的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

目录
  • 一、分布式锁方案比较

  • 二、ZooKeeper实现分布式锁

    • 1、方案一

    • 2、方案二

一、分布式锁方案比较

方案实现思路优点缺点
利用 MySQL 的实现方案利用数据库自身提供的锁机制实现,要求数据库支持行级锁实现简单性能差,无法适应高并发场景;容易出现死锁的情况;无法优雅的实现阻塞式锁
利用 Redis 的实现方案使用 Setnx 和 lua 脚本机制实现,保证对缓存操作序列的原子性性能好实现相对复杂,有可能出现死锁;无法优雅的实现阻塞式锁
利用 ZooKeeper 的实现方案基于 ZooKeeper 节点特性及 watch 机制实现性能好,稳定可靠性高,能较好地实现阻塞式锁实现相对复杂

二、ZooKeeper实现分布式锁

这里使用 ZooKeeper 来实现分布式锁,以50个并发请求来获取订单编号为例,描述两种方案,第一种为基础实现,第二种在第一种基础上进行了优化

2.1、方案一

流程描述:

ZooKeeper分布式锁的实现方式

具体代码:

OrderNumGenerator:

public class OrderNumGenerator {    private static long count = 0;        public String getOrderNumber() throws Exception {        String date = DateTimeFORMatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());        String number = new DecimalFormat("000000").format(count++);        return date + number;    }}

Lock:

public interface Lock {        public void getLock();        public void unLock();}

AbstractLock:

public abstract class AbstractLock implements Lock {        @Override    public void getLock() {        if (tryLock()) {            System.out.println("--------获取到了自定义Lock锁的资源--------");        } else {            // 没拿到锁则阻塞,等待拿锁            waitLock();            getLock();        }    }        public abstract boolean tryLock();        public abstract void waitLock();}

ZooKeeperAbstractLock:

public abstract class ZooKeeperAbstractLock extends AbstractLock {    private static final String SERVER_ADDR = "192.168.182.130:2181,192.168.182.131:2181,192.168.182.132:2181";    protected ZkClient zkClient = new ZkClient(SERVER_ADDR);    protected static final String PATH = "/lock";}

ZooKeeperDistrbuteLock:

public class ZooKeeperDistrbuteLock extends ZooKeeperAbstractLock {    private CountDownLatch countDownLatch = null;        @Override    public boolean tryLock() {        try {            // 创建临时节点            zkClient.createEphemeral(PATH);            return true;        } catch (Exception e) {            // 创建失败报异常            return false;        }    }        @Override    public void waitLock() {        // 创建监听        IZkDataListener iZkDataListener = new IZkDataListener() {            @Override            public void handleDataChange(String s, Object o) throws Exception {            }            @Override            public void handleDataDeleted(String s) throws Exception {                // 释放锁,删除节点时唤醒等待的线程                if (countDownLatch != null) {                    countDownLatch.countDown();                }            }        };        // 注册监听        zkClient.subscribeDataChanges(PATH, iZkDataListener);        // 节点存在时,等待节点删除唤醒        if (zkClient.exists(PATH)) {            countDownLatch = new CountDownLatch(1);            try {                countDownLatch.await();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        // 删除监听        zkClient.unsubscribeDataChanges(PATH, iZkDataListener);    }        @Override    public void unLock() {        if (zkClient != null) {            System.out.println("释放锁资源");            zkClient.delete(PATH);            zkClient.close();        }    }}

测试效果:使用50个线程来并发测试ZooKeeper实现的分布式锁

public class OrderService {    private static class OrderNumGeneratorService implements Runnable {        private OrderNumGenerator orderNumGenerator = new OrderNumGenerator();;        private Lock lock = new ZooKeeperDistrbuteLock();        @Override        public void run() {            lock.getLock();            try {                System.out.println(Thread.currentThread().getName() + ", 生成订单编号:"  + orderNumGenerator.getOrderNumber());            } catch (Exception e) {                e.printStackTrace();            } finally {                lock.unLock();            }        }    }    public static void main(String[] args) {        System.out.println("----------生成唯一订单号----------");        for (int i = 0; i < 50; i++) {            new Thread(new OrderNumGeneratorService()).start();        }    }}

2.2、方案二

方案二在方案一的基础上进行优化,避免产生“羊群效应”,方案一一旦临时节点删除,释放锁,那么其他在监听这个节点变化的线程,就会去竞争锁,同时访问 ZooKeeper,那么怎么更好的避免各线程的竞争现象呢,就是使用临时顺序节点,临时顺序节点排序,每个临时顺序节点只监听它本身的前一个节点变化。

流程描述:

ZooKeeper分布式锁的实现方式

具体代码

具体只需要将方案一中的 ZooKeeperDistrbuteLock 改变,增加一个 ZooKeeperDistrbuteLock2,测试代码中使用 ZooKeeperDistrbuteLock2 即可测试,其他代码都不需要改变。

public class ZooKeeperDistrbuteLock2 extends ZooKeeperAbstractLock {    private CountDownLatch countDownLatch = null;        private String beforePath;        private String currentPath;    public ZooKeeperDistrbuteLock2() {        if (!zkClient.exists(PATH)) {            // 创建持久节点,保存临时顺序节点            zkClient.createPersistent(PATH);        }    }    @Override    public boolean tryLock() {        // 如果currentPath为空则为第一次尝试拿锁,第一次拿锁赋值currentPath        if (currentPath == null || currentPath.length() == 0) {            // 在指定的持久节点下创建临时顺序节点            currentPath = zkClient.createEphemeralSequential(PATH + "/", "lock");        }        // 获取所有临时节点并排序,例如:000044        List<String> childrenList = zkClient.getChildren(PATH);        Collections.sort(childrenList);        if (currentPath.equals(PATH + "/" + childrenList.get(0))) {            // 如果当前节点在所有节点中排名第一则获取锁成功            return true;        } else {            int wz = Collections.binarySearch(childrenList, currentPath.substring(6));            beforePath = PATH + "/" + childrenList.get(wz - 1);        }        return false;    }    @Override    public void waitLock() {        // 创建监听        IZkDataListener iZkDataListener = new IZkDataListener() {            @Override            public void handleDataChange(String s, Object o) throws Exception {            }            @Override            public void handleDataDeleted(String s) throws Exception {                // 释放锁,删除节点时唤醒等待的线程                if (countDownLatch != null) {                    countDownLatch.countDown();                }            }        };        // 注册监听,这里是给排在当前节点前面的节点增加(删除数据的)监听,本质是启动另外一个线程去监听前置节点        zkClient.subscribeDataChanges(beforePath, iZkDataListener);        // 前置节点存在时,等待前置节点删除唤醒        if (zkClient.exists(beforePath)) {            countDownLatch = new CountDownLatch(1);            try {                countDownLatch.await();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        // 删除对前置节点的监听        zkClient.unsubscribeDataChanges(beforePath, iZkDataListener);    }        @Override    public void unLock() {        if (zkClient != null) {            System.out.println("释放锁资源");            zkClient.delete(currentPath);            zkClient.close();        }    }}

“ZooKeeper分布式锁的实现方式”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: ZooKeeper分布式锁的实现方式

本文链接: https://www.lsjlt.com/news/296735.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • ZooKeeper分布式锁的实现方式
    本篇内容介绍了“ZooKeeper分布式锁的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录一、分布式锁方案比较二、ZooKeep...
    99+
    2023-06-20
  • Zookeeper的分布式锁的实现方式
    这篇文章主要讲解了“Zookeeper的分布式锁的实现方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Zookeeper的分布式锁的实现方式”吧!1. 背景最近在学习 Zookeeper,...
    99+
    2023-06-05
  • 分析ZooKeeper分布式锁的实现
    目录一、分布式锁方案比较二、ZooKeeper实现分布式锁2.1、方案一2.2、方案二一、分布式锁方案比较 方案 ...
    99+
    2024-04-02
  • 使用Zookeeper实现分布式锁
    目录什么是临时顺序节点?Znode分为四种类型1.持久节点 (PERSISTENT)2.持久节点顺序节点(PERSISTENT_SEQUENTIAL)3.临时节点(EPHEMERAL...
    99+
    2022-11-13
    Zookeeper分布式锁 分布式锁 使用分布式锁
  • Zookeeper如何实现分布式锁
    这篇“Zookeeper如何实现分布式锁”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Zookeeper如何实现分布式锁”文...
    99+
    2023-06-27
  • zookeeper分布式锁如何实现
    这篇文章主要介绍“zookeeper分布式锁如何实现”,在日常操作中,相信很多人在zookeeper分布式锁如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”zookeeper分布式锁如何实现”的疑惑有所...
    99+
    2023-06-27
  • zookeeper实战之实现分布式锁的方法
    目录一、分布式锁的通用实现思路二、ZK实现分布式锁的思路三、ZK实现分布式锁的编码实现1、核心工具类实现2、测试代码编写线程安全问题复现使用上面封装的ZkLockHelper实现的分...
    99+
    2022-11-13
    zookeeper分布式锁 zookeeper实现分布式锁 zookeeper分布式锁原理
  • Java如何实现ZooKeeper分布式锁
    这篇文章主要介绍了Java如何实现ZooKeeper分布式锁,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。什么是分布式锁在我们进行单机应用开发,涉及并发同步的时候,我们往往采...
    99+
    2023-06-29
  • InterProcessMutex实现zookeeper分布式锁原理
    原理简介: zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且其他节点就会监听序号比自己小的节点,...
    99+
    2024-04-02
  • ZooKeeper的Curator分布式锁怎么实现
    本篇内容介绍了“ZooKeeper的Curator分布式锁怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Curator中有着更为标准...
    99+
    2023-06-29
  • ZooKeeper能否用于分布式锁的实现
    是的,ZooKeeper可以用于分布式锁的实现。ZooKeeper是一个分布式协调服务,可以用来实现分布式系统中的一些共享资源管理问...
    99+
    2024-03-07
    ZooKeeper
  • 基于Zookeeper实现分布式锁详解
    目录1、什么是Zookeeper?2、Zookeeper节点类型3、Zookeeper环境搭建4、Zookeeper基本使用5、Zookeeper应用场景6、Zookeeper分布式...
    99+
    2024-04-02
  • 怎么用springboot+zookeeper实现分布式锁
    本篇内容主要讲解“怎么用springboot+zookeeper实现分布式锁”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用springboot+zookeeper实现分布式锁”吧!Inte...
    99+
    2023-06-29
  • 基于Zookeeper怎么实现分布式锁
    这篇文章主要介绍“基于Zookeeper怎么实现分布式锁”,在日常操作中,相信很多人在基于Zookeeper怎么实现分布式锁问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”基于Zookeeper怎么实现分布式锁...
    99+
    2023-06-22
  • springboot+zookeeper实现分布式锁的示例代码
    目录依赖本地封装配置测试代码JMeter测试InterProcessMutex内部实现了zookeeper分布式锁的机制,所以接下来我们尝试使用这个工具来为我们的业务加上分布式锁处理...
    99+
    2024-04-02
  • C# 实现Zookeeper分布式锁的参考示例
    目录  分布式锁   Zookeeper分布式锁原理  C#实现Zookeeper分布式锁  分布式锁    互联网初期,我们系统一般都是单点部署,也就是在一台服务器完成系统的部署,...
    99+
    2024-04-02
  • redis和zookeeper中怎么实现分布式锁
    redis和zookeeper中怎么实现分布式锁,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。   一、基于redis的分布...
    99+
    2024-04-02
  • Redis分布式锁的实现方式
    目录一、分布式锁是什么1、获取锁2、释放锁二、代码实例上面代码存在锁误删问题:三、基于SETNX实现的分布式锁存在下面几个问题1、不可重入2、不可重试3、超时释放4、主从一致性四、Redisson实现分布式锁1、pom2...
    99+
    2023-04-03
    Java Redis分布式锁实现方式 实现Redis分布式锁 Redis分布式锁实现
  • InterProcessMutex实现zookeeper分布式锁原理是什么
    这篇“InterProcessMutex实现zookeeper分布式锁原理是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2023-06-29
  • Spring Boot整合Zookeeper实现分布式锁的场景分析
    目录一、Java当中关于锁的概念1.1.什么是锁1.2.锁的使用场景1.3.什么是分布式锁1.4.分布式锁的使用场景二、zk实现分布式锁2.1.zk中锁的种类:2.2.zk如何上读锁...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作