开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情”
前言
之前已经讲过了java在只有一台服务器情况下使用关键字synchronized互斥锁。因为多台服务器之间jvm是互相不影响的。所以我们就需要一个外部平台,来帮助我们控制多台服务器,来帮助我们实现互斥锁。
什么是分布式锁
分布式锁的定义就是满足分布式系统或集群模式下多进程可见并且互斥的锁。下图就是满足分布式锁的一些条件。
上面的关键字synchronized是在单体情况下解决的一些资源共享的问题(比如在同一情况下查询数据库)。而分布式锁就是在集群模式下也能资源共享。下面来介绍几种实现分布式锁的方式(主要介绍redis具体实现)。
redis实现分布式锁
首先是基于setnx这个命令实现的锁。命令使用的格式如下
//SET if Not eXists".
setnx lock.key lock.value
尤其是最后一句话说明了这个很适合作为锁,因为只有在不存在的情况下才会设置成功这个键。我们将对应的key何value设置好之后。其他的线程执行这条命令就会失败,从而避免了缓存击穿。
存在的问题
但是这样仍有两个问题就是当线程A拿到锁之后,发生异常,无法正确执行锁的释放。在上一篇我们说过解决的方法是给锁加上个时间期限,到时之后自动删除。锁删除之后,对应的线程b进来拿到锁。这时线程A正常了,开始释放b拿到的锁。所以为了避免这样的问题我们需要加锁是给锁加一个名称。每个线程只有对应名称的锁才能释放。
补充其他分布式锁的做法
首先就是数据库,然后是基于Zookeeper的分布式锁。大家感兴趣可自行搜索。