概念
分布式锁是控制分布式系统之间同步访问共享资源的一种方式,在分布式系统中,常常需要协调他们的操作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
实现方案
目前主流的有三种方式
1.基于redis
2. Redisson
3.zookeeper

一、Redis
一定要用SET key value NX PX milliseconds 命令如果不用,先设置了值,再设置过期时间,这个不是原子性操作,有可能
在1.设置过期时间之前宕机,会造成死锁(key永久存在)
这个是为了在解锁的时候,需要验证value是和加锁的一致才删除key。
使用redis做分布式锁的缺点在于:如果采用单机部署模式,会存在单点问题,只要redis故障了。加锁就不行了。
redis分布式锁实现代码参看:https://gitee.com/itgaofee/reids-soa-lock
二、主流分布式锁的解决方案 Redisson
1.redisson所有指令都通过lua脚本执行,redis支持lua脚本原子性执行
2.redisson设置一个key的默认过期时间为30s,如果某个客户端持有一个锁超过了30s怎么办?
这样的话,就算一直持有锁也不会出现key过期了,其他线程获取到锁的问题了。
Redission的具体实现代码参看:https://gitee.com/itgaofee/redission-demo
三、zookeeper
Zookeeper是一种提供配置管理、分布式协同以及命名的中心化服务。
临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点。
事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端。当前zookeeper有如下四种事件:
基于以上的一些zk的特性,我们很容易得出使用zk实现分布式锁的落地方案:
1.使用zk的临时节点和有序节点,每个线程获取锁就是在zk创建一个临时有序的节点,比如在/lock/目录下。
2.创建节点成功后,获取/lock目录下的所有临时节点,再判断当前线程创建的节点是否是所有的节点的序号最小的节点
3.如果当前线程创建的节点是所有节点序号最小的节点,则认为获取锁成功。





