iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Spring Boot整合Zookeeper实现分布式锁的场景分析
  • 567
分享到

Spring Boot整合Zookeeper实现分布式锁的场景分析

2024-04-02 19:04:59 567人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录一、Java当中关于锁的概念1.1.什么是锁1.2.锁的使用场景1.3.什么是分布式锁1.4.分布式锁的使用场景二、zk实现分布式锁2.1.zk中锁的种类:2.2.zk如何上读锁

温馨提示本篇文章要求掌握zk的数据结构,以及临时序号节点!

zk实现分布式锁完全是依靠zk节点类型当中的临时序号节点来实现的

一、Java当中关于锁的概念

1.1.什么是锁

锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源。

1.2.锁的使用场景

以减库存为例,库存这时候就剩1个,那么我们得保证只会有1个请求真正的完成减1操作,假如代码逻辑是,先从库里查库存,通过if条件判断,如果有就减,没有就返回购买失败。

这时候并发访问减库存接口,可能这时候我们代码当中的if判断已经失效了,多个请求同时查到还有一个,并且已经进入了if判断,没有加锁的话,这时候事情就比较严重了,库存一下子就成了负数。

对于这块代码我们不希望同时有人减库存,这时候就需要加锁来控制,加完锁之后,就是将并发请求改成了串行,也就是不管并发了多少个请求,我通过加锁,只让1个请求进行减库存,你们去争抢锁资源吧,谁先抢到了就是谁的。

1.3.什么是分布式锁

分布式锁是控制 微服务集群 之间同步访问共享资源的一种方式。

1.4.分布式锁的使用场景

使用分布式锁前提:微服务一定是集群,这里的微服务不是指的zk,而是指的我们的业务模块,在项目当中一般的,由于并发量较高,往往会将业务拆分为一个模块一个模块,例如订单模块,库存模块,拆模块其中一个目的就是为了针对于模块的并发性进行集群部署,比如订单模块用的比较多,我可以搭建多个订单模块,但是尽管他们的模块是多个,围绕的数据还是共通的(一个数据库)。

集群情况下,我们在代码加普通锁已经解决不了问题,假如现在有三个库存微服务,设置了负载均衡的方式访问,普通锁只能控制自己的服务减库存不会出现负数,但是他控制不了其他两个服务,数据是共通的,所以这时候只能使用分布式锁,通过分布式锁来控制三个服务当库存只有一个商品的时候,只能有一个服务访问的请求可以减库存成功。

二、zk实现分布式锁

2.1.zk中锁的种类:

  • 读锁:创建⼀个临时序号节点,节点的名称会包含READ的字母,表示是读锁,⼤家都可以读,要想上读锁的前提:之前的锁没有写锁
  • 写锁:创建⼀个临时序号节点,节点的名称会包含WRIT的字母,表示是写锁,只有得到写锁的才能写。要想上写锁的前提是,之前没有任何锁

读锁和写锁完全是按照创建的临时序号节点的名称来区分的!

  • 序号节点创建出的节点,根据先后顺序,会在节点之后带上⼀个数值,越往后执⾏数值越⼤,类似于Mysql的主键自增
  • 临时节点 :临时节点是在会话结束后,⾃动被删除的,通过这个特性,zk可以实现服务注册与发现的效果。假如会话关掉后大概10s左右,创建的临时节点就会消失。这个会话就是指的连接zk的客户端。
  • 临时序号节点:就是上面两个的结合体

当需要上锁的时候,就进行创建临时序号节点,释放锁的时候就删除节点。

2.2.zk如何上读锁

  • 创建一个临时序号节点
  • 获取当前zk中序号比自己小的所有节点
  • 判断最小节点是否是读锁:
  • 如果不是读锁的话,则上锁失败,为最小节点设置监听。阻塞等待,zk的watch机制会当最小节点发生变化时通知当前节点,于是再执行第二步的流程
  • 如果是读锁的话,则上锁成功

想要上读锁,主要就是需要看比他小的节点当中是否有写锁。如果有写锁,就需要等他用完之后删除节点,通过watch机制来通知他,写锁已经释放,然后他再进行第二步判断。

在这里插入图片描述

2.3.zk如何上写锁

  • 创建一个临时序号节点
  • 获取zk中所有的子节点
  • 判断自己是否是最小的节点:
  • 如果是,则上写锁成功
  • 如果不是,说明前面还有锁,则上锁失败,监听最小的节点,如果最小节点有变化,则回到第二步。

在这里插入图片描述

2.4.⽺群效应

如果⽤上述的上锁⽅式,只要有节点发⽣变化,就会触发其他节点的监听事件,这样的话对zk的压⼒⾮常⼤,——⽺群效应。可以调整成链式监听。解决这个问题。

在这里插入图片描述

假如并发了100个请求都需要获取写锁,这时候创建了100个节点来监听最小节点,当最小节点发生变化的时候,意味着他一下子要进行通知100个节点,zk瞬间会压力非常大。

所以这时候可以采用链式监听,链式监听仍然是依靠的序号节点的特点。就好比mysql设置自增后,不管多少并发请求,他仍然能保证id的唯一性,zk的序号节点同样也是。让他们都不再监听最小节点,而是监听他的上一个节点。当上一个节点释放锁后,那当前节点就可以创建写锁了。

这里还会遇到一个问题,假如他的上一个节点意外删除了,但是并不是等着拿到锁后释放锁,而是单纯的不想等了,所以删除了节点,而上面还有很多节点加着锁呢,所以我们不能单纯的靠上一个节点删除后当前节点就进行加锁。我们加写锁要保证的是,他上面没有任何节点加锁。这时候让他进行监听上上个节点即可。假如上上个节点仍然有问题了,那就监听上上上个节点。总之一点就是尽量避免不让多个节点同时去监听一个节点

三、springboot整合分布式锁

springboot整合curator客户端:https://www.jb51.net/article/181082.htm

我直接是基于上一篇文章当中的项目进行 分布式锁 练习的!

根据上面提到的zk分布式锁实现思路,我们其实并不用去自己写,在curator客户端已经给我们提供了现成的方法,我们只需要简单的调用客户端提供的方法,就可以实现分布式锁功能!

@Autowired
CuratorFramework curatorFramework;


@Test
void testGetReadLock() throws Exception {
    // 读写锁
    InterProcessReadWriteLock interProcessReadWriteLock = new
            InterProcessReadWriteLock(curatorFramework, "/lock1");
    // 获取读锁对象(创建对象耗时也就18毫秒)
    InterProcessLock interProcessLock = interProcessReadWriteLock.readLock();
    System.out.println("等待获取读锁对象!");

    // 获取锁(假如一直没拿到锁这个方法一直会是阻塞的,就算不阻塞的情况下,这个方法耗时也是特别长,高达17秒)
    interProcessLock.acquire();

    // 正常的我们代码假如走到了这一步,说明已经获取到锁了,这里写相关的业务代码即可,执行完记住释放锁
    System.out.println("获取到了锁!");
    for (int i = 1; i <= 100; i++) {
        Thread.sleep(3000);
        System.out.println(i);
    }
    // 释放锁(方法耗时13毫秒)
    interProcessLock.release();
    // 走到这一步的时候节点已经被删除了
    System.out.println("等待释放锁!");
}


@Test
void testGetWriteLock() throws Exception {
    // 读写锁
    InterProcessReadWriteLock interProcessReadWriteLock = new
            InterProcessReadWriteLock(curatorFramework, "/lock1");
    // 获取写锁对象
    InterProcessLock
            interProcessLock = interProcessReadWriteLock.writeLock();
    System.out.println("等待获取写锁对象!");
    // 获取锁(假如一直没拿到锁这个方法一直会是阻塞的)
    interProcessLock.acquire();
    for (int i = 1; i <= 100; i++) {
        Thread.sleep(3000);
        System.out.println(i);
    }
    // 释放锁
    interProcessLock.release();
    System.out.println("等待释放锁!");
}


@Test
void testGetReadLock1() throws Exception {
    testGetReadLock();
}

这个是两个获取读锁的时候的节点场景:

在这里插入图片描述

这个是一个获取读锁,一个获取写锁的场景,然后读锁节点是0004,所以是后创建的,他只有等待0003释放写锁,才能获取到读锁。

在这里插入图片描述

zk分布式锁会产生死锁吗?

这个肯定是不会的,因为假如有客户端拿到了锁,还没释放,服务挂了,这时候依据临时节点的特性,当临时节点和客户端断开连接几秒后会自动删除的,删除节点也就意味着自动释放锁!

正常情况不建议使用zk作为分布式锁,效率属实太慢。

到此这篇关于Spring Boot整合ZooKeeper实现分布式锁的文章就介绍到这了,更多相关Spring Boot整合Zookeeper分布式锁内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring Boot整合Zookeeper实现分布式锁的场景分析

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

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

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

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

下载Word文档
猜你喜欢
  • Spring Boot整合Zookeeper实现分布式锁的场景分析
    目录一、Java当中关于锁的概念1.1.什么是锁1.2.锁的使用场景1.3.什么是分布式锁1.4.分布式锁的使用场景二、zk实现分布式锁2.1.zk中锁的种类:2.2.zk如何上读锁...
    99+
    2022-11-13
  • 利用consul在spring boot中实现分布式锁场景分析
    因为在项目实际过程中所采用的是微服务架构,考虑到承载量基本每个相同业务的服务都是多节点部署,所以针对某些资源的访问就不得不用到用到分布式锁了。 这里列举一个最简单的场景,假如有一个智...
    99+
    2022-11-12
  • 分析ZooKeeper分布式锁的实现
    目录一、分布式锁方案比较二、ZooKeeper实现分布式锁2.1、方案一2.2、方案二一、分布式锁方案比较 方案 ...
    99+
    2022-11-12
  • Spring Boot整合流控组件Sentinel的场景分析
    目录一、百度百科1、Sentinel 特性2、Sentinel 的开源生态二、Sentinel 的历史三、Sentinel 基本概念1、资源2、规则四、sentinel的优势五、Se...
    99+
    2022-11-12
  • Spring boot 整合 Redisson实现分布式锁并验证功能
    目录简述1. 在idea中新建spring boot工程并引入所需依赖2. 编写相关代码实现3. 模拟实际环境验证3.1 下载idea的docker插件并配置相关镜像信息3.2 将s...
    99+
    2022-11-13
  • Spring Boot 实现Redis分布式锁原理
    目录分布式锁实现引入jar包封装工具类模拟秒杀扣减库存测试代码方案优化问题1:扣减库存逻辑无法保证原子性,问题2:如果加锁失败,则会直接访问,无法重入锁总结分布式锁实现 引入jar包...
    99+
    2022-11-13
    Spring Boot 实现Redis分布式锁 Spring Boot  Redis分布式锁
  • ZooKeeper分布式锁的实现方式
    本篇内容介绍了“ZooKeeper分布式锁的实现方式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!目录一、分布式锁方案比较二、ZooKeep...
    99+
    2023-06-20
  • 分布式面试分布式锁实现及应用场景
    目录引言1、面试官:你有遇到需要使用分布式锁的场景吗?事件A:事件B: 2、面试官:Redis分布式锁实现方法1、基于Redis的分布式锁3、面试官: 那解锁操作...
    99+
    2022-11-13
  • Zookeeper的分布式锁的实现方式
    这篇文章主要讲解了“Zookeeper的分布式锁的实现方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Zookeeper的分布式锁的实现方式”吧!1. 背景最近在学习 Zookeeper,...
    99+
    2023-06-05
  • SpringBoot整合Redisson实现分布式锁
    目录一、添加依赖二、redis配置文件三、新建配置类四、使用分布式锁可重入锁读写锁信号量(Semaphore)闭锁(CountDownLatch)Redisson是架设在redis基...
    99+
    2022-11-12
  • ZooKeeper的Curator分布式锁怎么实现
    本篇内容介绍了“ZooKeeper的Curator分布式锁怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Curator中有着更为标准...
    99+
    2023-06-29
  • ZooKeeper三分布式锁实现及完整运行的代码
    本文小编为大家详细介绍“ZooKeeper三分布式锁实现及完整运行的代码”,内容详细,步骤清晰,细节处理妥当,希望这篇“ZooKeeper三分布式锁实现及完整运行的代码”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧...
    99+
    2023-06-29
  • spring boot 动态生成接口实现类的场景分析
    目录一:定义注解二:建立动态代理类三:注入spring容器四:编写拦截器五:新建测试类在某些业务场景中,我们只需要业务代码中定义相应的接口或者相应的注解,并不需要实现对应的逻辑。 比...
    99+
    2022-11-12
  • Spring Boot中怎么利用Redis实现分布式锁
    Spring Boot中怎么利用Redis实现分布式锁,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。分布式锁介绍Spring Boot 实现 Redis 分布式锁在 sprin...
    99+
    2023-06-16
  • springboot整合curator实现分布式锁过程
    目录springboot curator实现分布式锁理论篇:实操篇:项目实际应用中分布式锁介绍锁的介绍悲观锁-数据库锁悲观锁-缓存锁分布式锁—zookeepersprin...
    99+
    2022-11-13
  • SpringBoot整合Redisson如何实现分布式锁
    这篇文章将为大家详细讲解有关SpringBoot整合Redisson如何实现分布式锁,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Redisson是架设在redis基础上的一个Java驻内存数据网格(In...
    99+
    2023-06-25
  • ZooKeeper框架教程Curator分布式锁实现及源码分析
    目录  如何使用InterProcessMutex  实现思路   代码实现概述  InterProcessMutex源码分析&nb...
    99+
    2022-11-13
  • zookeeper实战之实现分布式锁的方法
    目录一、分布式锁的通用实现思路二、ZK实现分布式锁的思路三、ZK实现分布式锁的编码实现1、核心工具类实现2、测试代码编写线程安全问题复现使用上面封装的ZkLockHelper实现的分...
    99+
    2022-11-13
    zookeeper分布式锁 zookeeper实现分布式锁 zookeeper分布式锁原理
  • Spring Boot 集成Redisson实现分布式锁详细案例
    目录前言分布式锁实现引入jar包Redisson的配置application.yml中引入redisson.yml配置redisson.yml配置封装Redisson工具类模拟秒杀扣...
    99+
    2022-11-13
    Spring Boot 集成Redisson Spring Boot 分布式锁
  • C# 实现Zookeeper分布式锁的参考示例
    目录  分布式锁   Zookeeper分布式锁原理  C#实现Zookeeper分布式锁  分布式锁    互联网初期,我们系统一般都是单点部署,也就是在一台服务器完成系统的部署,...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作