00:00
好,同学们,接下来我们完成了lock unlo脚本和微服程序的整合,为了达到更加通用,我们引入设计模式的考虑,那么大家可以看一下考虑扩展性的问题,我们本次啊,是ready实现分布式锁,没错,你只为了应付当前的工作,可以把它写死啊,但是弟兄们以后如keepper my SQ通通都要过来了,那你怎么办呢?因为我们一旦要考虑一个自研的东西,你必须考虑适配性、通用性和扩展性。来,弟兄们来看一下啊,Java里面有哪些方法可以获得?那么第一种弟兄们都清楚,就是对应的缺少什么,你有什么对吧?比如说我们这儿呢,多少狗,我缺条狗,有条狗,我相信弟兄们呢,肯定呢,也不陌生。
01:00
OK,第二种同学们你们干什么?这个是不是全部写死啊,对吧?只能是狗,通用性极差。这也是我们大家在学加vac的时候hello的初级篇,那么这个时候你是不是应该想到第二步,是不是叫多肽OK,负类的引用可以指向子类的实例,那么左边等号左边干嘛不能写死,到最后等号右边也不要写死,让我们的程序是活的,那这个时候怎么写呢?那是不是可以定一个animal动物类,假设这叫A等于尿,这边可以是不是可以尿鸡鸭猫狗鱼?弟兄们能理解这个意思吧?所以说这样情况下是左边是接口,右边是具体的实现内,最经典的是不是list list等于new are list list list等于new link list list list等于new VE,不废话了,这个都清楚。第三种,弟兄们。
02:00
复习咋整,你只是左边写死了,我现在是不是需要你右边能够有一种方式,因为左边是规范,当然要写死,不是接口就是抽象类,但是右边的话。你只能是一个我们希望是动态的,那么这样是不是多态满足了,再加动态等号,右边的具体落地的实现内不要写死啊,那么这时候弟兄们我们干什么?那么最右边我们是不是一般可以提交给spring容器管理,或者是一一大堆的什么石化技术,OK,那么第四种,比如说我们现在都明白以前user service接口,User service user service等于new user service input实现类一样的吧,后面我们是不是交给容器管理,是at注解标签那些东东,或者我们这儿写了一个线程,本来是要利用一个线程,但是我们是不是可以通过实化技术好第四种,那么是不是就是结合我们的设计模式,比如说最经典的spring可以通过工厂设计模式直接通过传递。
03:16
参数。从工厂获得OK,各种顺序,这无所谓啊,你只要要明白我们获得对象等号右边的这个具体落地实例,对实例化这个对象可以拿下来,那么所以说搁到这儿,弟兄们我们呢,引入工厂设计模式来将其改造,你传给我的参数是red,我这个工厂给你做red版本的分布式锁,你给我传输keepper,我给你设计red版本哦,传keepper给你设计从工厂里面获得zoo keepper版本的那个分布式锁,MYSQ传MYSQL版本的分布式锁,OK,所以搞到这,弟兄们我们来设计一个分布式锁的工厂,那么来,注意包也是放在这好重要代码,我们呢,一步一步手抄,请同学们耐心一点点搁到这,弟兄们艾特工厂纳入到。
04:18
Spring容器管理,诶,杨哥有B个,你每一步都会特别注重类头的这个纳入容器管理,什么service ctrl了,CT啊,组件等等,为什么这个上面空空如也,什么都没写好,留着这么一小问题,那接下来我们这个工厂搞定,那么干嘛呢?Private这个工厂是不是也要是什么我们的string right temp这么说能跟上好或者这样吧,可能有些同学会懵逼啊,说你这个变量是怎么定义出来的,干脆这样,咱们先写主要的业务逻辑吧,Public look,咱是不是要满足lock接口对吧,Get distribuor。
05:02
那么这个呢,Lock,好,我这那么就是lock type,兄弟,你传的锁的类型是什么?Register我就给你弄register我就给你弄的版本,那么默认这个工厂啥也不知道,没人启动,我当然不用知道好了,那接下来呢,如果lock type等等,那那对不起,Return,那OK,那如果正常情况下look type.ok那么干嘛呢?这个时候我们呢,忽略大小写啊,Ready,比如你传的时候,你给我传的是red的话,那咱就要给你建立一个东西,那么这个东西是不是刚才我们所说过的look name,固定的手写的red分布式所就是杨哥这个。
06:02
YY work,好,那么基于此,我们这儿private string look nameme,这么说弟兄们好不好?搁到这this.lock内就等于我们的,因为锁的这个K是可以写死的,对吧?我们图方便,那么第二个如果是有这个以后,相当于我们这儿就不再写死啊,听懂我们要从工厂里面获得这个话实例化的这对象,所以搁到这了以后我们就要瑞return又出来这么一个东西,那么现在这个东西是不是就是我们的?这个参数叫look克内,但是现在告诉我有这个吗?没有,所以弟兄们干嘛直接拿过来好,那么隔到这儿,Out容器自动注入,那意思就是如果你传的是red,从这个工厂你传red,我就给你打造一个分布式所,那么其他呢?L衣服呢?
07:13
那弟兄们,如果这个look type啊,他呢,将将好等于的是我们的zoo keep,那你晓得的我们这呢,是不是就可以是一样的这么写在这儿,我是不是叫keepper这个ready look了,对吧?然后呢,瑞return一个new的我们一个什么东东好,那么todo我们的keepper。版本的分布式所OK弟兄们没有任何问题吧?那么当然这个呢,我们就不再展开了,好,那如果下面啊还有什么的这个呃,比如说再写一个啊,我们可以实现right分数的很多啊,假设呢,这个是呢,我们就写个MY,那么这呢建一个key对吧?那么这儿呢,我们就不再写这些问题了,那么组keep,那是不是建一个keep的那样一个lock node叫节点对不对?那么这我们就是MYSQ对应的版本,OK,那么弟兄们这个是不是就是我们对应的工厂设计模式,这么说能跟上弟兄们O不OK,那么当然啊,这儿呢,写严谨一点,那么现在呢,通通都没有,别到时候呢,你调用了以后的话呢,不出出一些问题,好吧,好了,那么这个呢,我们工厂模式搞定,那接下来第。
08:52
同学们,改吧改吧,搁到这正常情况下,我们是不是一般都习惯于纳入容器来进行管理了,但这块没必要理由,我这个类不是通过容器获得,我这个类大家请看,是通过工厂里面给我直接溜出来这个东东啊,哎,所以呢,我们这儿说一下,那么就是引入了我们的这个工厂类,然后呢,从工厂获得即可,好好了,那么弟兄们,其他的没什么,那么如果我们为了程序好调试,我这就没有用logo后介了啊,那么在这呢,我们可以呢,嗯,打印出来我们。
09:48
对应的啊,需要的这些参数,那么这些什么参数呢?比如说我们的na好加上这个罗克内好再加上啊,那有了这个锁倒是没什么好说,主要的时候就是UUID这个value对不对,那个。
10:11
定时定死的这个超时时间是50秒钟,这个倒无所谓,那弟兄们这是不是就是我们的拥有IDY6,再加上我们的U用ID,弟兄们O不OK好,如果说是这个是一个,那么解锁这那么大家呢也可以看一下啊,都可以这个来进行我们对应的操作,好,干脆解锁这先不加吧,因为日志太多了,也比较烦,那么来弟兄们到这一波完成这个我们呢已经写完了,这个呢,我们呢也已经全部写完成,OK,最后是不是在service里面要使用这个工程模式了,那么弟兄们该怎么用呢?那么来弟兄们lower这话我就不废话了啊,直接呢弄过来,主要的写完了这个意思大家也就明白了。首先我们呢,获得依赖著说我们的distributed。
11:11
这个工厂拿到好了,那这个工厂拿到了以后弟兄们搁到这儿请看。是不是从这个工厂里面传个write进去,获得我们的write lock,然后lock直接过到这儿啊,Lock彻彻底底完成了我们的结偶,我们没有写死,左边是写死的,可以就是一个锁的规范,反正对外暴露lock按lock,但是右边是灵活的拿着工厂你传什么我就给你返回什么类型的锁,不管是write u keep还是MYOK,好,那么弟兄们,基于此我们呢,全部的7.1这个版本的改造通过,接下来开始测试。
12:05
通过上面的分析和代码的改造,我们引入了工厂模式,成功的实现了依赖注入加程序结耦。那么来弟兄们,我们一边启动我们的微服务,一边来进行对应的代码的复习和讲解。这块主要业务逻辑扣减库存不说了,过关键就这两行一句话,以前我们是需要什么就念什么要么。通过容器或线程磁化技术获得,那么下面我们呢,自研的话呢,我们用了工厂设计模式,需要什么通过船舱达到了等号,右边的截偶左边就是一套接口规范,那么对外报落洛安洛完了以后,底层洛安洛均由我们的撸R脚本来保证了实现,并且单独测试过撸R脚本成功,通过那么嵌进我们的微服务Java程序来实现我们对应的工厂模式和UR脚本不可中断的特性来完成我们的lock UN诺克。好了,那么同学们启动以后我们准备一下数据,老规矩,001号仓库5000个,那这个时候我们呢,来看一眼,5000个没问题,那么现在这把锁还没有执行,当然就没有了,对吧?二话不说,下面开测,那么开测的前提呢,咱们也就不测单机了,直接上吉米塔。
13:34
压测,那么压测通过单击肯定OK对吧?那么好,那么弟兄们,我们呢,后台清干净,这个时候呢,5000个请求搁到这儿一直行好了,那么同学们老爷来同学们看一下那它是多少?给他慢慢跑着,反正我们的库存100%应该是什么?哎,大家请看,时有时无才正确加锁成功了哪个请求流水ID又有I对应的线程编号是谁?几次一次对吧?那么来同学们,那么来再看一下我们的get库存,那么现在还有428,如果能够成功的减到零,那是不是代表我们呢本次程序。
14:16
压测通过OK好了,那么听学们怎么样,到零了吧,那到最后,那么同学们揉眼成功卖出一个商品,库存还剩0O不OK妥了吧,所以呢,搞到这我们呢,程序在压测情况下通过,压测通过以后,那么同学们我们自然而然。会发出灵魂拷问,那杨哥你不整天说可重入性,可重入性的测试吗?没见你测可重入性啊,那么接下来我们呢,暂停一下我们的微服务,完了以后呢,改造程序搁到这,这些不动故意的啊,在这完成以后,咱们是不是说过五我进这个业务以后,同样一个线程又进来一次,又把这个lock按洛来了一次,那么看看你的可重入性是否能够保证好了,那么同学们,咱们呢,开工test这个时候呢,我们的这个叫re enry OK,那没有这个方法直接自动化生成,我们搁到这儿它也不用干什么,和前面的原模原样好,那干脆呢,我诊断。
15:35
那拷贝下来他也不用返回个什么东东,业务逻辑呢,极其简单,来吧,那么同学们这些代码大家呢,没有任何问题对吧,不再说了,他这就干一件事。干什么呢?测试可重入佛,好,那么看看呢,我们的代码能不能够成功,相当于说在就就跟我们以前讲的这个re lock里面。
16:08
Lock lock啊,Lock啊,Lock是不是lock最外层的lock里面又嵌进了一个lock and lock,哎,所以说你按照我们勾UC里面lock克接口的规范,你只要写一个牛逼的分布式,所是一定要按照洛克接口的规范考虑可重复性,所以我们这相当于这落克搁到这儿,只不过我把这一段又重新抽了一个方法,同学们能理解能跟上吧。好了,那接下来呢,我们呢,来看一眼微服,接下来我们准备开始可重入性能的测试,呃,干脆这样啊,在启动微伏之前,我们为了给它好测,我把这个锁的过期时间改小一点,25秒钟啊,它这样的话测起来就快一点。第二个问题呢,我们这是lock try lock,这有一个打印出的所的key和UUID,这是其实这个try lock其实就是lock的这部分,对吧,然后为了好。
17:08
啊,我再unlo这我也给大家呢进行打印,那么这样可重入的话,Lo几次unlo几次,那么这样打印出来的数据就应该匹配,最终我们在这的话呢,调用这个动洞的话,那这句话是不是应该打出来呀,好同学们给它微服务启动,我们只是为了好调试啊,稍微做了一点这个后台提示的变更,那接下来同学们看一下啊,在这款库存是有的,4996,然后这把锁目前呢是空的,好微服务启动以后,我们呢,直接呢来进行一下我们对应的测试,那这个地址那么之前呢,已经有过,我翻出来过,好将其准备好,微服务成功启动,那么来同学们一回车,大家请看。以前是不会有其他问题的,它会马上出来,但是现在大家请看是不是在这转圈圈,好回到我们这,同学们请看,同学们请看是不是减少了一个,确实卖出去一个流水号有了现场ID是31,下面请看后台弟兄们lawyer这个时候第一次落克是不是一一四一三十一,然后卖出去一个,然后哎呀哎呀报bug了,那么同学们loe这个又有ID,线程是31,没问题,这个发现3787,哎,应该是同一个请求流水号U用ID应该一样,同一个线程,31313131,这个没问题,大家请看,按照我们说的洛克了几次啊,Unlo克几次啊,那么我内部是不是又欠了一份洛克,Unlo克,同学们这个没问题吧。
18:55
那下面出问题的bug程序是UUID出现了不同和变更,所以到后面第二次删的时候,它会告诉你干嘛这把锁不存在,因为U悠ID变化了,所以我们目前写的程序是有bug的,同样一个请求线程过来,同学们look,我进来,这我获得锁同一个线线程,这个线程ID是多少?3131 3131,这个没问题,但是流水号是不是变成了两个,一个是C1,一个是八七,那说明我们程序一定有什么地方是不周正,没有完全达标的,那么同学们这个就是可重入所你需要考虑的问题,不排除有些业务它进去以后,他又要调用这个洛克,那这个时候大家请看我们问题出在哪啊?回到我们的脑图笔记可以获得。
19:55
结果是线程ID倒是同一个,说明还是同一个请求线程,但是UUID它不一样了,最外层的洛,红色对红色,最外层按洛,内部的蓝色对蓝色,按洛,和洛又匹配。
20:15
由重入bug,由于ID不一致,线程ID32323232倒是OK,那么大家思考一下,我们该如何修改我们这个程序呢?那我把代码发给各位同学们,请琢磨琢磨,并思考一下我们的bug究竟出在什么地方?那接下来我们要进行引入工厂模式7.2版本的改造,一句话,通过前面的案例介绍,我们已经明白了,同样是31线程ID,这个没问题,但是请求的UUID出现了问题,导致我们的路亚脚本最终。按lock来这删除的时候,它这个参数一由于我们前面的UID已经不一样了,导致删除失败,识别不认同,所以我们来分析我们的程序,大家请看杆在哪,工厂模式这我们每次一个落的时候,同学们看一眼咱们red啊,在这块我们调用这个方法,工厂里面调用它每次得到一个怎么过来的,是不是拗过来的,拗过来的话提到这个方法,这个是由这依赖中枢传入的,不变lock内写死啊。
21:40
区别是不是就在这相当于我每拗一次啊,我这个流水ID是不是动一次啊,哎,所以说大家请看现在出的问题是线程ID31,三四个,31没问题,我lock了两次,按lock两次,共计打出四行后台日志啊,但是流水号却有了两个,所以我们的突破口要解决这个流水号,那么在这儿这个流水号这样的解决方法有非常多,那最经典的你是不是可以用我们的thread local,每个线程含有自己的,这是第一种,那么第二种我们呢,用个最简单通用的重新改吧改吧,我们对应的分布式所的这个工程,那每一次请求我们干脆就想这么干,第一个我们呢,直接定义一个string,然后又用ID,弟兄们,没问题吧,但是呢,我们这儿通过的是构造方法,这个构造方法就让他有又用ID,因为啊,当我们。
22:41
要去依赖注入的时候,相当于在这儿,因为工厂是有铁金有一个对吧,这个没有任何问题,通过这样的容器管理以后,这个工厂里面可以制造多种red分布式锁好了,那么在这我一旦获得就像是初始化加载一样,就会有一个这样的一个东西叫UUID,好,那这个UUID怎么来的呢?
23:05
由这个API拿过来,那么大家请看这个时候一过来是不是UID好了,我们从工厂这就带着UUID,这个就是有点类似于全局,全局唯一的一个把这个UUID在传进去,就跟我们从顶层传lock克内给子类去用100%同一个不变一样,由工厂顶层传用于ID下去,顶层传下来100%同一个好了,那么隔到这儿我们呢,就需要修改一下我们这个的构造方法,我们弟兄们这一波没问题吧,好了,这是以前的啊7.1这个版本咱们就注掉了,那把这些呢通通拿过来来,同学们现在呢,就会变成由上面的负类传递UUI。
24:05
D再结合我的线程,各自的线程ID,那么这样是不是保证我的u u ID value就是有且仅有一个且是同一个,不管你重入几次我都能够健康使用啊OK,好,那么同学们接下来咱们呢,启动一下我们微服务测试,看一下我们这样的思路是否能够落地通过,好,我先暂停一下录屏启动成功我们继续,那接下来看一下这个,看一下这个现在还有4995对吧,不废话,后台呢,干干净净改了以后一回撤大家请看,不再转圈了吧,马上告诉你4994端口号是7777,好了,请看后台同学们漏眼16C1流水号31 16C1流水号31,那么大家请看是不是进去以后第一次最外层这个落口加勒索成高卖出去一个,然后。
25:05
干嘛?对不起,又落,这是第二个落,然后大家请看测试可重入,然后安lock,这个是内部的lock,安lo,这是测试可重入锁,没问题吧,说明我同一个请求同一个线程进来,持有的锁可以自己取得自己的,不会作茧自缚,这个就是满足了可重入性的要求,你在写look的时候一定要考虑这个特性,否则你写的look不OK,不通用的。那么最外层大家请看是不是这个和这个是什么安洛克,基于此,我们的单机测试通过16C1OK好了,那么同学们微负摆在这儿口说无凭,That inventory老规矩,咱现在是不是又给他恢复成5000来,同学们get来。没问题吧,干嘛回到我们这儿,是不是JA me塔下面的高并发测试哦,你得通过好打开我们的测试脚本搁到这来同学们搁到这儿全部把后台的聚合报告删掉,在这儿继续写个5000,当然啊,你这可以拆分写,比如说是50乘以200啊,或者多少多少都可以啊,我这图省事,反正就5000个来了,那么一跑朋友们搂眼是不是后面疯狂打,那么来看一下我们的,那么跟以前的老规矩一样,绝对不会再出现浏览器这有转圈了吧,对不对?所以说呢,不停的刷刷刷刷刷,后台的话呢,进去又进来,进去又进来,总之一句话,没有被可重入锁困住,而且也实现了我们的right分布式锁。那么来同学们该请看,该删的删,该用的用,没问题吧,好,现在GET001237120971858,你看基本上一秒。
26:57
干去一两百个对吧?好,那么如果它能够成功的减到零,就说明我们在高并发减me的压力测试下面顺利通过我们的可重入锁,满足了我们的最终所得规范和落地要求。OK,好,同学们怎么样,到零了吧?所以最终我们的库存零打完收工,OK,好,搞到这儿我们会发现这个它是引入了工厂模式改造7.2版本,我们改了两次对吧?从7.1~7.2整体构成了我们的7.0最终的版本,所以这个分布式所工厂该怎么改这个构图方法。
27:39
直接获取从工厂传过来的这个UUID啊,我们把这个UUID放到父类这往下注入,这样就会保证它的流水号和线程ID是流水号不变线程ID,那么就是每一个请求线程自动自动由系统分配线程ID,这是不会重复的,对吧?好了,全部单击并发可重入性全部测试通过,那么同学们基于此我们的7.0版本的可重入锁将我们的引入工厂设计模式,达到解耦的目的,完整测试通过,请同学们动手,自己能不能够写一下对应的案例,好,接下来继续往前。
28:21
自动续期。
我来说两句