本地锁
浏览器把100w请求由网关随机往下传,在集群情况下,每台服务都放行10w请求过来,这时候每台服务都用的是本地锁是跨JVM的, 列如这些服务都没有49企业,此时有几个服务进行回原了打击在DB上面,那后期把这个服务部署了N台,N台用的都是自己的锁,是锁不住的
分布式锁第一阶段
让微服务都去公共位置去,列如Redis去抢占坑位利用setnx命令,如果是1了,操作成功,是1变成0操作失败,
问题:如下图如果抢到锁了 业务在执行期间机器宕机或停电了,后面解锁业务没有执行到,锁一直在,其他服务如果还想获取到这个锁,就会导致永远获取不到这个锁了,所以得引入过期时间
分布式锁第二阶段
引入过期时间后即使业务爆炸等10s以后再自行删除
问题:如果执行过期时间的时候停电了,导致这行代码没有设置上,所以加锁和过期时间必须是一起的保证原子性操作。
分布式第三阶段
为了保证原子性可以使用set key value EX “过期时间” NX,加锁+过期时间 用原子操作没问题了
极端情况:
假设锁10s过期,
- A运行9.5s业务结束开始删锁,给redis发请求。速度慢
- redis第10s锁过期自动删除,然后B抢到了锁,这个锁是B,B已经开始执行业务了
- B执行业务的时候,A删锁命令顺着网线爬到redis。直接调用del lock,删除了这个key。导致删除了B的锁的错误。B锁没有,其他C可能又进来。两个人都在执行业务,没锁住
分布式锁第四阶段
为了避免解别人的锁,利用UUID作为每个线程自己锁的唯一值
问题解除锁的时候可能会解到别人的锁
分布式锁终极阶段
利用Lua脚本删除锁