分布式锁的这三种实现90%的人都不知道
一、为什么要使用分布式锁我们在开发应用的时候 , 如果需要对某一个共享变量进行多线程同步访问的时候 , 可以使用我们学到的Java多线程的18般武艺进行处理 , 并且可以完美的运行 , 毫无Bug!
注意这是单机应用 , 也就是所有的请求都会分配到当前服务器的JVM内部 , 然后映射为操作系统的线程进行处理!而这个共享变量只是在这个JVM内部的一块内存空间!
后来业务发展 , 需要做集群 , 一个应用需要部署到几台机器上然后做负载均衡 , 大致如下图:
文章插图
上图可以看到 , 变量A存在JVM1、JVM2、JVM3三个JVM内存中(这个变量A主要体现是在一个类中的一个成员变量 , 是一个有状态的对象 , 例如:UserController控制器中的一个整形类型的成员变量) , 如果不加任何控制的话 , 变量A同时都会在JVM分配一块内存 , 三个请求发过来同时对这个变量操作 , 显然结果是不对的!即使不是同时发过来 , 三个请求分别操作三个不同JVM内存区域的数据 , 变量A之间不存在共享 , 也不具有可见性 , 处理的结果也是不对的!
如果我们业务中确实存在这个场景的话 , 我们就需要一种方法解决这个问题!
为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行 , 在传统单体应用单机部署的情况下 , 可以使用Java并发处理相关的API(如ReentrantLock或Synchronized)进行互斥控制 。 在单机环境中 , Java中提供了很多并发处理相关的API 。 但是 , 随着业务发展的需要 , 原单体单机部署的系统被演化成分布式集群系统后 , 由于分布式系统多线程、多进程并且分布在不同机器上 , 这将使原单机部署情况下的并发控制锁策略失效 , 单纯的Java API并不能提供分布式锁的能力 。 为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问 , 这就是分布式锁要解决的问题!
二、分布式锁应该具备哪些条件在分析分布式锁的三种实现方式之前 , 先了解一下分布式锁应该具备哪些条件:
1、在分布式系统环境下 , 一个方法在同一时间只能被一个机器的一个线程执行;
2、高可用的获取锁与释放锁;
3、高性能的获取锁与释放锁;
4、具备可重入特性;
5、具备锁失效机制 , 防止死锁;
6、具备非阻塞锁特性 , 即没有获取到锁将直接返回获取锁失败 。
三、分布式锁的三种实现方式 目前几乎很多大型网站及应用都是分布式部署的 , 分布式场景中的数据一致性问题一直是一个比较重要的话题 。 分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance) , 最多只能同时满足两项 。 ”所以 , 很多系统在设计之初就要对这三者做出取舍 。 在互联网领域的绝大多数的场景中 , 都需要牺牲强一致性来换取系统的高可用性 , 系统往往只需要保证“最终一致性” , 只要这个最终时间是在用户可以接受的范围内即可 。
在很多场景中 , 我们为了保证数据的最终一致性 , 需要很多的技术方案来支持 , 比如分布式事务、分布式锁等 。 有的时候 , 我们需要保证一个方法在同一时间内只能被同一个线程执行 。
基于数据库实现分布式锁;
基于缓存(Redis等)实现分布式锁;
基于Zookeeper实现分布式锁;
1.基于数据库实现排他锁方案1
表结构
文章插图
获取锁
INSERT INTO method_lock (method_name, desc) VALUES ('methodName', 'methodName');
对method_name做了唯一性约束 , 这里如果有多个请求同时提交到数据库的话 , 数据库会保证只有一个操作可以成功 。
推荐阅读
- iQOO 7官方美图赏:三种配色、速度美学设计传承
- 可与ASML实现联机!国产光刻机传来喜讯,张绍忠预言或成真?
- 烟台港“管道智脑系统”上线 在国内率先实现原油储运全息智能排产
- 想实现《曼达洛人》的数字布景吗?索尼模块化屏幕即将开售
- 快递员工也能当“教授”?上海快递工程技术高级职称评审实现突破
- 骁龙888首次实现可变分辨率渲染 创造沉浸式游戏体验
- 柔宇FlexPai 2实现多次重复折叠无折痕,斩获CES 2021创新奖
- 飞步无人车:实现首个混线工况下的自动驾驶集卡编队独立整船作业
- 荣耀、高通相继宣布,雷军迎来大敌?任正非的预言正在实现
- 李炳忠自我打脸,去年realme销量翻番的目标远未实现