redis
这个目的是加锁
setifabsent(key,value,time,timeunit.seconds) //设置key的存活时间,原子语句
看锁是否能够加上,如果存在key值上面的方法返回false,对系统调用error
加锁执行业务逻辑
释放锁
为什么要加时间呢!finally执行不到呀,就会造成永久性锁。
带来一个问题 事务比较长的化,如15s的操作10s另一个线程进来进行加锁,再过5s 线程A将锁释放,之后C线程可以进来
刚加的锁永久失效!
解决方法
设置value值为uuid ,在释放锁的时候进行判断,如果此时加锁的value值与生成uuid相同,
代表的是自己释放了自己,而不是别人释放的。
这还有个问题,此时key过期了 ,别人可以拿到锁造成了死锁问题
解决方法
开启子线程不断的给对象延长加锁时间 (定时器或者while循环 时间设置为有原来的1/3)
可以使用redission解决。
实现步骤类似于上面
通过一个key值取锁,然后进行加锁过程,之后释放锁
线程1 执行Redisson 判断是否可以进行加锁,加锁就对资源业务处理,另外的线程cas等待
还有问题 主从复制情况下 A挂了,B当选,但是B没有同步过来
REDLock
基本思想就是多个master
请求一个master,设置自动失效时间还有超时时间,超时时间是为了防止master宕机了之后,客户端还在等待结果
服务器没有在规定时间相应,尝试去另一个redis实例请求获取锁。
客户端从当前时间-获取锁时间=得到锁的时间。且在redis实列超过n/2几点获取锁 与得到的所时间小于失效时间才算获取成功。
有效时间-获取锁的时间 = 锁使用的时间
锁失败,客户端应该在所有redis进行解锁。
zookeeper
dubbo 选择zookper当成注册中心
kafaka 选择zookper
zookper 文件系统的数据结构,但是目录也是可以存储数据的
持久化节点 临时节点(通过session创建) 持久化顺序节点 临时顺序节点 容器节点(子节点删除,父节点删除,分布式锁) ttl节点
时间监听 (对目录节点,普通节点进行监听)
注册中心 注册到节点上 实现监听
羊群效应 一个节点释放锁 999个等待 再释放998等待
使用顺序节点解决。
可靠性!
ps
以后扩展,补图操作