本文小编为大家详细介绍“基于curator怎么实现分布式锁”,内容详细,步骤清晰,细节处理妥当,希望这篇“基于curator怎么实现分布式锁”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、锁的应用场景:在单体应用中,我们会使用ReentrantLock或Synchronized来应对并发场景。比如最常见的卖票场景,假如总共有100张票,线程A和线程B同时操作,如下图:这时有一个共享变量100,线程A和B将100拷贝到自己的工作内存中,当线程A抢到执行权的时候,此时A工作内存中的值是100,然后售票,进行自减操作,将自己工作内存中的值变成了99。当A还没来得及将99刷回到主内存的时候,线程B进来了,此时B拿到的主内存的值还是100,然后售票,进行自减,也是99。这就出现了同一张票出售了两次的情况。所以我们会加锁加volatile保证原子性保证可见性。2、分布式锁是什么?上面的场景中,我们可以通过ReentrantLock或者Synchronized搞定,因为你的项目只运行在一台服务器上,只有一个JVM,所有的共享变量都加载到同一个主内存中。而分布式应用中,一个项目部署在多台服务器上,最基本的架构如下图:比如现在server1、server2和server3读取到数据库的票数都是100,在每一个server中,我们可以用JDK的锁来保证多个用户同时访问我这台server时不会出问题。但问题是,如果client1访问到的是server1,票数是100,然后购票,还没来得及将数据库票数改为99,client2也开始访问系统购票了,client2如果访问的是server1,自然不会出问题,如果访问的是server2,这时server2读取到数据库的票数还是100,那么就出问题了,又出现了同一张票卖了两次的情况。在分布式应用中,JDK的锁机制就无法满足需求了,所以就出现了分布式锁。3、分布式锁应该满足的条件:4、分布式锁的实现方式:1、建表:2、思路:当执行一个方法的时候,我们首先尝试往表中插入一条数据。如果插入成功,则占锁成功,继续往下执行,执行完删除该记录。如果插入失败,我们再以当前方法名、当前机器ip+线程id、数据被操作时间为5分钟内(5分钟表示锁失效的时间)
为条件去查询,如果有记录,表示该机器的该线程在5分钟内占有过锁了,直接往下执行最后删除记录;如果没有记录,占有锁失败。一个用户就是一个线程,所以我们可以把机器ip和用户id组合一起当成dl_device_info
。3、占有锁和释放锁:如果insert失败,则:4、小总结:以上表结构可能并不是很好,只是提供了这么一个思路。下面说它的优缺点:1、原理:基于redis的set key value nx ex 30
,这条语句的意思就是如果key不存在就设置,并且过期时间为30s,如果key已经存在就会返回false。如果要以毫秒为单位,把ex
换成px
就好了。我们执行方法前,先将方法名当成key,执行这条语句,如果执行成功就是获取锁成功,执行失败就是获取锁失败。2、代码实现:3、小总结:优点:简单易用,一条redis命令就搞定。可以设置过期时间,避免释放锁失败造成其他线程长时间无法获取锁的问题。缺点:这种做法只适合redis是单机的时候,如果redis有集群,这样做就会出问题。假如一个线程在master上获取锁成功了,在master还没来得及将数据同步到slave上的时候,master挂了,slave升级为master。第二个线程进来尝试获取锁,因为新的master上并没有这个key,所以,也能成功获取到锁。解决办法:针对上面的缺点,我们可以采用redis的RedLock算法。假如集群中有n个redis
,我们先从这n个redis中尝试获取锁(锁的过期时间为x
),并记录获取锁的消耗的总时间t
,获取锁成功数量为s
,当且仅当t = (n/2 + 1)
时,认为获取锁成功。1、是什么?官网地址:https://github.com/redisson/redisson/wiki/Table-of-Content Redisson是一个功能十分强大的redis客户端,封装了很多分布式操作,比如分布式对象、分布式集合、分布式锁等。它的分布式锁也很多,什么公平锁、可重入锁、redlock等一应俱全,下面来看看如何在springboot项目中使用它。2、使用redisson做分布式锁:3、小总结:以上就是使用redisson做分布式锁的简单demo,用起来十分的方便。上面是与springboot项目集成,直接用它提供的springboot的starter就好了。用它来做分布式锁的更多用法请移步至官网:redisson分布式锁。1、zookeeper知识点回顾:zookeeper有四种类型的节点:持久节点:默认的节点类型,客户端与zookeeper断开连接后,节点依然存在持久顺序节点:首先是持久节点 香港云主机,顺序的意思是,zookeeper会根据节点创建的顺序编号临时节点:客户端与zookeeper断开连接后节点不复存在临时顺序节点:客户端与zookeeper断开连接后节点不复存在,zookeeper会根据节点创建的顺序编号2、基于zookeeper实现分布式锁的原理:我们正是利用了zookeeper的临时顺序节点来实现分布式锁。首先我们创建一个名为lock
(节点名称随意)的持久节点。线程1获取锁时,就在lock
下面创建一个名为lock1
的临时顺序节点,然后查找lock
下所有的节点,判断自己的lock1
是不是第一个,如果是,获取锁成功,继续执行业务逻辑,执行完后删除lock1
节点;如果不是第一个,获取锁失败,就watch排在自己前面一位的节点,当排在自己前一位的节点被干掉时,再检查自己是不是排第一了,如果是,获取锁成功。图解过程如下:线程1创建了一个lock1,发现lock1的第一个节点,占锁成功;在线程1还没释放锁的时候,线程2来了,创建了一个lock2,发现lock2不是第一个,便监控lock1,线程3此时进行就监控lock2。直到自己是第一个节点时才占锁成功。假如某个线程释放锁的时候zookeeper崩了也没关系,因为是临时节点,断开连接节点就没了,其他线程还是可以正常获取锁,这就是要用临时节点的原因。说清楚了原理,用代码实现也就不难了,可以引入zookeeper的客户端zkClient
,自己写代码实现(偷个懒,自己就不写了,有兴趣的可以参考我zookeeper的文章,肯定可以自己写出来的)。不过有非常优秀的开源解决方案比如curator,下面就看看curator怎么用。1、springboot整合curator:在确保zookeeper成功启动了的情况下,执行这个单元测试,最后回到linux中,用zkCli.sh连接,查看是否成功创建节点。2、使用Curator做分布式锁:Curator封装了很多锁,比如可重入共享锁、不可重入共享锁、可重入读写锁、联锁等。具体可以参考官网:curator分布式锁的用法。打开一个浏览器窗口访问,后台打印出获取锁成功的日志,在1分钟之内,开启另一个窗口再次访问,打印出获取锁失败的日志,说明分布式锁生效了。读到这里,这篇“基于curator怎么实现分布式锁”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注开发云行业资讯频道。
这篇文章主要为大家展示了“电脑系统崩溃如何使用U盘重装win8系统”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“电脑系统崩溃如何使用U盘重装win8系统”这篇文章吧。准备工作提前制作一个U盘启动盘,具体制作步骤大家…
免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。