00:00
好,各位同学,我们继续,接下来我们就要重新思考并设计我们的新版的带有可重入性满足这个功能的red分布式锁,结合我们当前的业火,我把它分为一横一纵。首先目前呢,我们有两条分支哦,目的是保证同一个时候只能有一个线程持有锁。进去库存里面做扣减库存的动作。说白了。一个人进来拿到锁了以后,然后去调库存模块减个一,所以呢,这两个分支分别是第一个保证re分布式锁加锁和解锁的成功,也就是我们的洛克安洛克。第二个扣减库存的red命令的原子性,点一下扣减一个库存,卖出去一件,那么回到这儿,我们的程序就变成这样,中间这块各位亲,就是我们的业务逻辑,那也就是我们的这个第二个命令分支扣减库存red命令原子性,这个好解决,也就是大家所见过的除外这块就是红色这一段,减减一个库存完活,OK,那么这儿不用多说,那么这个里面也就是我们的扣减库存对吧,减减就完了,这是我们的业务逻辑,难的是。
01:37
这需要有一个我们对标的什么东东,兄弟们是不是叫lock,这干完活以后是不是需要有一个我们对标的什么东东,弟兄们是不是安洛克好不好,那么这块整明白了以后,我们就要来了,之前啊各位亲,我们初始第一步啊,我们用的是sat塔NX,前面讲过了,如果你不考虑可重入性,一般的小产用到这儿够用,但是它不完美,那么结合我们这我们要进一步的深化,咱要满足我们后面的aqs这样的一种编写所的规范接口行为,对吧?所以我们不得不考虑可重入性。
02:37
那导致这样的结果就是改进板我们呢,不可以再用sat NX了啊,SX无法很好的做到对可重入性的支持,所以结合到这,我们只好用这一票脚本来搞定,第一步先判断有没有red分布式锁,有。
03:05
看看是不是自己的,也就是是不是对应的流水号加自己,有的话加个一,如果可重录了再加个一,每重录一次加个一,这是第二步,第三步解锁,每次减个一,一直减到零为止,这个安洛克,最后删掉这把分布式锁,那么搁到这儿了以后我们会明白,那么我们改进的话,那改成个什么鬼样子呢?所以我们这边得到的一个结论就说我们的SNX命令不好使了,我们需要用的是h set,用哈希模型来替代。OK,那么基于此,就会推出我们下面要做的两个工作。
04:02
我们的洛克这一个方法和我们的安洛这个方法全部被要求换为我们的lur脚本来进行实现,听懂了吗?因为大家可以看加锁这一大段和检索这一大段和最后删索这一大段,100%有一反L词的各种判断,所以引出了我们下面的对应的一个篇章,那么也就是说我们要用落R脚本来实现我们对标的lock按lock操作。接下来我们将会对lock啊,Lock这两个方法进行相应的改进,把它们全部变成落脚本。下面在开始编写撸R脚本之前,先回顾一下我们的思路,那么弟兄们呢,都清楚啊,按照我们的这个设计,中间这一坨叫扣减库存,也就是我们业务逻辑两个分支之一,就TRY这块不多说了,点一下减一个过好理解。那么下面我们要干的事就是最好按照我们要用一个锁的规范,那么是不是就是洛克和安洛克对吧?相当于说在这lock按lock你封装两个方法换以前我们已经解决了对应的red分布式锁相关的常用问题,但是一旦要考虑到可重入性和锁的规范,我们需要进一步的抽取和。
05:40
优化,我们希望把这一段抽进去一个方法里面,叫洛克,我们把这一段抽进一个方法里面,按洛克,看着赏心悦目,程序简洁好。在抽方法的过程当中,我们突然发现枷锁和解锁要考虑一种东西叫可重入性,所以我们现在对不起SNX2。
06:09
不好用了,我们需要用我们的h set这么一个动作,所以呢,把lo unlo这两个方法都需要用落R脚本来落地实现,所以本节讲的重点就是要用落R脚本来重写我们的look啊look这两段程序来,为什么呢?请看命令过程分析,刚做的首先。要满足可重入,我们来这么干,先判断有没有right分布式所,有咱们用,没有咱们就新建,比如说这我们没有,我们新建,那么就是ready分布式所,这个T还要具体指定是哪个流水号哪个线程的,然后进来OK,到这代表返回这个一键索成功,这位请求线程获得了red分布式所,那么如果它没有可重弱,那么直接就是用完以后直接DELETE1删掉就完了,但是他要考虑可重弱,那么就是洛克几次安洛克几次。所以基于此,我们呢把步骤分解,先判断right分布式组这个K是否存在,我们呢先用exist key这么来干,那么同学们请看这是不是不存在好了,那么如果说返回零说明不存在,那么h set叫新建当前线。
07:41
成属于自己所,我们呢,用流水号加线程ID来,各位亲,是不是我们的h set key value可重入次所,接下来如果在这块是返回一了,说明已经有阳格的那把分布式所,也就说已经有这个T了,那这个时候我们需要进一步判断是不是自己的。
08:06
然后如果是自己的,那假设啊,哎,这个锁里面有没有这个锁有了进一步判断,这个锁里面是不是自己的,如果不是,那不好意思啊,不是自己的,什么都不做。但如果说返回一说明是自己的锁,表示我又重新进来了,一次自增一次表示重入,OK,所以h in quick by就要把它写上,那么100%要用到上述各种带if l l if l的lur脚本比较复杂,那么为了给同学们讲清楚,我写一步一步一步的大家写清楚,分三个版本逐步迭代,同学们不要离开。跟着走。接下来我们的工作就是把上面这些流程步骤改为我们的加锁的撸R脚本,好,那么分解动作三步带大家写出最终版本,并通过测试来。那么接下来这个就是加锁的路R脚本,对标我们的lock方法。好,第一步我们先要判断。
09:22
有没有这个所有咱们再判断是不是自己的,然后可重入,没有咱们是不是要新建,所以呢,If red点括哪个命令,Exist是不是存在我们对应的这个K,如果说不存在,那学们干嘛呢?新建哪一个新建命令啊,Red Co用哪个命令新建是不是我们的h set好对标我们的这个key完了以后value是哪个呢?是不是UUID加我们的这个线程ID的值哦,好进来几次啊,是不是一次新建乘高,那register或我们说过为了防止死索和氮气那些毛病,任何一个right分布式所它是不是要加一个东西叫过。
10:22
期时间OK,那么来同学们这个K,假设我们这儿呢,设大一点,就50秒钟吧。来了,如果上面都成功RETURN1我们搞定,否则的话l if,那么要么就是没有,反过来它这个值不是零就是一,如果这一段不进来,是不是进入肯定会走下面,走下面的话我们要判断是不是自己的red Co,那么搁到这儿就是我们的H一个exist,那么然后呢,我们对标的这个K,然后呢,我们对标的又用ID,我们的线程ID就是这个value值。二来看看等等一否等等一数才式我们自己的对吧?如果是我们自己的,那么同学们我们应该怎么办呢?拷贝过来好在这是不是就是我们的这个命令hqui by,听懂了吧?
11:37
然后呢,这个K,然后呢,又有ID说明什么,又进来了一次,那么只要进一次,我们就把这个时间加深一点,OK,那么这如果也成功了,就是我们的什么RETURN1,弟兄们if l到这能跟上吧,那么到最后对不起,根本就不是,那么就是我们的瑞RETURN0,最终N的if打完收工,弟兄们,这个h increase by。
12:09
和h set这两个命令和expire过期时间,这个就是我们第一版本来V1相关的编写好,我先暂停一下录屏,同学们可以先琢磨琢磨,理理这个思路,看一下,同学们继续回到我们的笔记,我们在这儿呢,对标一下。没有任何问题吧,那么来,当然啊,在这块的话呢,也就是我们刚才所说的编写的过程,带着大家亲自做了一遍,那啊当然这啊,呃,30秒或者50秒的话,随便你,那么接下来我们就要思考有没有改进的空间。那么同学们请看一下我们这个脚本有没有发现一个问题,蓝色部分都是一样的,只有金黄色这个部分它不一样,那么接下来就是相同部分是不是可以替换,那么这样我们的代码是不是更简洁,就可以写出我们第二版优化后的程序?那么这个时候找出不同点无非就是h set和h include by这两个命令用到的地方它不一样,我们得到的结论就是h in会半是否可以替代set命令。好,那么同学们,我们不妨呢来做一下我们对标的测试,那么red client连上好,Delete red lock把杨哥的分删掉了啊,下面我们的意思是这样的,那么假设我们直接h include by。
13:51
这个key就是杨哥这个red look现在是没有意思,就是说这个东东可不可以同时满足新建加自增一次,那假设这个负的啊,那么假设我们这个这个1112222,那么这个线程ID的话呢,那么我们呢,就写个七随便啊,这就是个一,同学们请看一回车反过来一得到一个结论,就说H1可半就。
14:19
包含了h set新建这个功能,那么来h get z z YY杨哥的right分布式锁哪个请大家看有没有没有任何问题吧,所以新建加自增一次同时成功,基于此,那么同学们,我们得到一个什么结论?是不是就可以改成我们的第二版这个程序?那么怎么改呢?弟兄们,第二版挪到这有点类似于合并相同的代码用。
15:00
H替代h set精简代码,好,那么同学们搞到这这些是不是都一样的?所以把这一大段整体拷贝好,我干些什么事呢?只是在这儿。这个条件判断它不一样,所以呢,各位亲,我们在这儿就是这个条件满足了进这,这个条件满足了进这,那么由于命令可以是一样的,好,HR in cry by是不是都可以,所以说这段代码是不是被干掉了,那杨哥这一波怎么说呢?然后这儿就是喔,转过来来,那么请大家告诉我,是不是这一段代码也被干掉了,听到于此啊,大家就看发现。
16:05
这个条件或者这个条件二者择其一,满足了,直接可以用这一段,就这三行代码搞定我们的全部工作和内容,这个就是我们的第二个版本。没问题吧,所以说弟兄们lower加一个关键字或这两个条件,则其夕全部拿下来好吧,那么最终弟兄们第三个版本我干嘛?是不是脚本OK,那么换上我们的参数来替代,听懂了吗?那么这可以蝼也那么基本上就是K1就是我们的阳格的R分布式所。ARGUE21,那么就是我们的U悠ID和线程ID那个Y最后是不是过期时间参数二号好吧,那么30秒40秒50秒随便你好了,那么在这。
17:10
我们呢就可以这么干,命令咱们呢也不动,那么这个key是不是就变成我们的大写的keys就变成这个,这个没问题吧,好,所有的key通通变成了这个,那么所有的value是不是变成了我们的那个二哥,那么弟兄们没问题吧,来了,接下来这个K。就变成这个,那么这个UUID就变成了这个,OK好了,那么这个K也就变成了我们的这个东东。最后这个过去时间50秒,兄弟们,这是不是要写成我们的二和二,没问题吧,其他都是照旧,所以我们的拿过来,这是我们的笔记的,那么弟兄们可以做一个详细的对比,那么OKK,那么二个一二通通没有什么太大的问题,那接下来弟兄们我们呢,自己写的这个简单的。
18:24
拿过来干什么呢?是不是对标折成一行,然后完了以后弟兄们,咱们是不是要测试一下,放到我们的red的客户端里面来进行对应的测试,OK,好,那么同学们,我们来进行一下测试来。三步三个版本怎么一步步迭代优化写为我们的V3这个版本的脚本编写完成,接下来测试演示,看看能不能通过把我们的第三版甩成一行直接复制,那么来吧,E搁到这就我们的脚本,然后大家都清楚啊,先加一个参数,说明有几个key,剩下的全是参数,好,那么这个参数就是number kiss几个一个我们的key叫杨哥的red lock好了,那么这个流水号加UUID呢,我们就懒得写了啊,那么杨哥这呢,偷个懒,直接呢拷贝过来一个粘到这,好,你的过期时间几秒,50秒,大家请看,返回一成功新建,OK,来,T TL register。
19:50
Look,还有多少秒,还有40秒,那么h get lock,好,这个field就是刚才我们这一堆弟兄们没有任何问题吧?OK,那么好,接下来假设那杨哥你再执行一遍,刚才是新建成功了,那么现在就是第一个条件搞到这儿啊。
20:13
那么来同学们,相当于说刚才第一个条件没有,你新建成功了,那接下来如果已经有了呢?来同学们我们再执行一次是不是一,再执行一次是不是一好,那么现在呢,同学们我们看一下这个TTL四十五百分之百,是不是执行一次又给他续期了,对吧?然后再过来同学们请看现在是几三,哎,这个才说明是什么。既满足了red锁新建,又保证了可重入性,这一套操作下来,我们才能用我们的lur脚本完全封装进去,一个look方法完成我们的功能set NX。
21:00
不再使用,请同学们务必切记好。那么来,各位亲,那么我们的加锁就给答案呢?说到这,测试通过脚本,OK,接下来我们就来说说阿诺克解锁。加锁完成以后,接下来我们来说一下解锁的rar脚本。Look对外暴露Java就是一个方法,但这个方法下面是有一大段复杂的R脚本if else的各种判断,且考虑了。高可右独占可重入性,那么一样,待会我们用unlo克也对外暴露,就是一个Java的unlo方法,它底子也要调用一段鲁瓦脚本来保证我们的可用和可重入的解锁。那老语言分析一下这个unlo克脚本该怎么写?首先我们的设计思路要有锁,铁还是自己的,不多讲。弟兄们,我们以前在写5.0版的时候,是不是写过这么一段脚本,你必须要防止张冠李戴,只允许自己去解锁自己,不允许你把别人的锁给删了,所以我们要先判断是不是自己的锁。第二个判断一下它可重入性,它加了几次我们就解锁几次,最后等你的。
22:31
锁的标签和那个标记是零的时候,就是加了三次,我解了三次,最终我们数字是零了,然后用delete给它删掉,三步还是比较啰嗦,同学们请看第一个,先判断一下。有没有锁,且这个锁是自己,OK,这个非常重要,来判断杨哥的这个锁,这个T里面有没有这个流水号,且这个线程ID有没有,如果没有,那对不起,返回零说明根本就没有锁,程序搞不定对吧。
23:06
返回那那假设不是零,说明有锁且是自己的锁,直接调用H1亏半负一表示每次减一个一,解锁一次,直到它变为零,表示可以彻底的删除该锁,我们再用吉delete塔给它搞定,那么同学们全套流程走一遍,假如我们从没有开始新建,然后重入重入,那么最终大家请看有没有这个锁,有了这个一代表有,然后再看看这个锁里面有没有它有,目前大家请看几次啊,进去了三次好吧,独占加可重弱进去了三次啊,那么为了满足这些性能,我们解是要解三次啊,所以在这儿减一三变二二,再减个一,二变一一,再减个一,变成零,注意零了以后才能删,最终迪丽塔把这个K给它删掉,删除成功,返回一打完收。
24:07
OK,所以说兄弟们,这个就是我们安洛克解锁的路亚脚本相关的设计,那么一句话又和刚才一样,我们呢,一步一步的要配合上我们的判断,把我们的上述设计改为录R脚本。解锁的路R脚本代码说话,通过测试走嗯,搁到这儿啊,我就对标这儿写一下这个来接下来我们的流程和操作就是解锁的路R脚本对标我们的安洛克方法,OK,来吧,那我们的思路说白了就是以它作为切入点,判断这两种情况啊,具体的说应该是三种啊,因为还有个delete塔,好,那么咱们来代码说话,如果red括h exist,假设有这个T,并且又有ID,这样的话,它等于零的话来搁到这。
25:18
等于零,同学们请看说明什么,根本就没有锁,程序该怎么写,返回一个难,所以瑞这是第一种情况,第二种情况,那这段程序是不是要么是零,要么是一,一的话,是不是肯定有,所以进入到我们的第二种情况进一步如果不是零。说明有锁,且是自己的锁,所以我们接下来就在这儿直接要调用H1亏半负一表示每次减一个一解锁一次。直到它变为零了以后,表示可以删除这个key delete干掉,OK,好,那么同学们,那么在这我们呢,然后呢,直接HR。
26:15
好,然后呢,我们干嘛呢,这个是不是我们的key,接下来这个是不是UU ID thread,这个ID弟兄们没问题吧,然后解这又是负一,意思就是说你要么就是没有返回,那要有的话说明。有且就是自己的,那么说明你有可重入的情况,咱呢点一下减一个,直到你减为零,Then干嘛呀,我呢来加你删除,那么就是我们的瑞return write cool,删什么呀,那么就是我们的delete,干嘛把对应的这个key删掉并返回,这是我们的第二种一个情况,最后那对不起,啥也没有返回一个零,那么摁打完收工,这个呢,就是我们的第一版本,弟兄们没问题吧,那么接下来我们干嘛呢?第二版本程序已经写完了,那么我们要做的是不是把我们的key替换成这个,把我们的value是不是替换成我们的参数一二个一对吧,所以呢。
27:36
第二套我们呢,搁到这儿,我们弟兄们,杨哥呢,就偷个懒啊,都是一些替换型的,我们把主要的代码写清楚就行了,那么大家请看H2 h2无非就是我换了个答案写好吧,K这个我们KE1参数没问题,Return一个这个东东,然后的话呢,我们的H1亏半,这些呢,我们呢也就不再废话,K1参数一负一,直接调用这个K变成K1,好吧,O了,那么所以说弟兄们直接转成一行,然后拷贝拿走,接下来我们呢,来进行我们对应的。
28:18
测试全套流程,OK,脚本编写完成,接下来咱们就来做一下解锁洛脚本,对标的安洛克脚本我们是否写的正确,自然弟兄们你要想按洛,且还要测试可重录性的解锁,那么是不是要先有洛克对吧?有洛克才能有按洛克,所以全套流程走下来,带着大家从洛克到按洛克,只压按摩走起来,兄弟们先用洛克加了三次,然后呢,在这判断解锁加了三次说明有可重入的问题,那么我加三次是不是要减三次蓝色的就是这个关键,那么我每次减一次,直到减为零,我才能够delete它,最终这个所变为钠,第一次减有没有减到零呢?没有,所以说返回。
29:19
0FIRST再减一次,现在是二,有没有到,有没有到零呢?没有再减一次,一减一等于零了,有没有到了这个一,然后呢,自动的调用delete塔把它删掉,然后我们来判断一下,再来一次,对不起,没有了,所以直接告诉你,你看他听懂好了,那么同学们,流程理论上通过我们接下来弟兄们,我们先保证干净,先删掉一个,那么来这个就是我们之前的加锁,一个两个三个没问题吧,那么好了,加锁成功以后,我们来看现在这个锁里面的这个T几次,三次,所以evil回到我们自己编写的脚本,拿过来你粘贴,然后我们叫什么呢?是不是也是叫。
30:19
这个一个参数啊,K就叫这个,然后呢,我们的value u u ID加线程ID就叫这个,那么来同学们请看我一回车一回车,你看现在还没有减围嘛,对吧,都是零,请看这个一听懂了吧,说明什么?已经吉丽塔删除成功了,再回车,那没有这个K了,前面你加了三次,我减了三次,然后一一旦它减为零的时候,就这段。OK,迅速delete。干掉了,干掉成功,所以返回一,那么这个T解锁成功,OK,弟兄们,这个就是我们安洛相关的脚本,并测试通过,那接下来兄弟们,咱们是不是可以进一步的写出我们的第七版的微服务程序,进一步的完善带着可重入功能的。
31:23
Java程序OK,好,那么接下来我们是不是需要将上述录R脚本整合进我们的微服务,彻彻底底实现我们刚才的设想,对外暴露,你不要去写这么多啦,兄弟,没你什么事了,那么多脚本我们已经用撸R脚本加锁的解锁的搞定一封抓对外暴落,我们自己提供的就是一个洛克,按洛克方法OK,彻彻底底对标我们的这一两个方法撸R脚本进行底层的支持和替换,好同学们进行期待,接下来我们讲更加精彩的跟微服务Java程序的整合。
我来说两句