陇西学做网站,廊坊网站搭建,科技 响应式网站模板下载,超市网上商城分布式锁#xff1a;
使用场景#xff1a;
通常对于一些使用率高的服务#xff0c;我们会进行多次部署#xff0c;可能会部署在不同的服务器上#xff0c;但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性#xff0c;我们需要对线程进行加锁#xff0c;…分布式锁
使用场景
通常对于一些使用率高的服务我们会进行多次部署可能会部署在不同的服务器上但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性我们需要对线程进行加锁但是因为我们部署在了不同的服务器上而互斥锁只针对加锁的那台服务器不会去限制别的服务器所以是不能实现强一致性的要求的。比如在8080的线程1获取完库存后8081的线程1也进行了获取此时8080的线程1对内存进行了扣除按理来说已经没有库存了但是8081的线程1获取的时候还是有的还会继续扣除这样就会出现问题 这个时候我们就要使用分布式锁来解决问题了分布式锁可以实现不同服务器上的监控只要有一个线程获取了锁其他的线程包括其他服务器上的线程都无法继续获取锁。 那么分布式锁怎么使用呢通常我们使用redis的时候会通过redis中的redission来实现分布式锁。
Redission redission实现分布式锁有三个重点
watch dog
我们知道获取了锁之后如果不去释放锁那么别的线程就都无法去使用相关的资源那么如果加锁的线程因为某些原因终止了没有去执行释放锁的命令怎么办呢也许我们可以去设置锁的时间到时间了就立马释放锁这种方法理论可行但是实际上每个线程需要花费的时间是无法确定的如果时间少了加锁就没有意义时间久了又占用资源。如果有一个旁观者它可以告诉我们线程是否结束如果结束了就释放锁如果没结束就给锁加时就好了。watch dog就可以实现这个功能。
在某个线程加锁的同时会生成一个新的线程来启动watch dog监控如果加锁线程没有结束watch dog会每隔releaseTime/3的时间做一次续期releaseTime默认30s如果线程结束了我们可以发送释放锁的指令来停止watch dog续期锁。
下面是redission的代码实现这里有一个要注意的地方如果我们在trylock的时候设置了锁自动释放时间redission就会认为我们可以自己控制什么时候释放锁就不会使用watch dog来帮助我们。 重试机制
当有线程获取锁后另外的线程会尝试循环获取锁不过这个次数不是无限制的存在一个阈值。
LUA脚本
加锁、设置过期时间等操作都是基于lua脚本完成可以保证代码的原子性。 除此之外redission生成的分布式锁还有一些特点
可重录 什么意思呢就是在同一个线程中可以多次进行加锁同一把锁而每加一把锁锁的value 1每释放一把锁锁的value -1。举个例子在add1方法中我们拿了一个“heimalock”锁此时这个lock的记录如下 因为生成了锁value为1在add1方法中我们又调用了add2方法add2方法同样也拿了一个“heimalock”锁此时并不会创建新的锁而是将value 1变成了2此时这个lock的记录如下 释放锁其实就是value -1不再过多赘述。
主从一致性
redission不能实现但是redission提供了redlock红锁来实现只不过效率太低如果要实现主从一致性建议使用zookeeper