00:00
接下来各位同学我们来看一下锁的种类,首先跳出我们Java本身,我们今天所说的是分布式锁,那我们就得唠唠了,一般说所同学们一定会想到我们之前学过的多线程是不是有个东西叫synchized。那么第二个。GUUC里面我们是不是讲过一个锁的接口叫lock接口,Lock按lock,那么我们已经有这两种锁了,为什么现在要讲一个东西叫red分布式锁,它的产生发生的条件是什么东东呢?那么来同学们请先看一下笔记,第一个传统的这个是单机版的锁,它指。起作用于同一个Java虚拟机以内,也就是我们传统的synchized或者lock接口下面,现问题是分布式环境下面有多个不同的Java虚拟机,比如说我每一台机上都装了Java,我们不转四台不同的服务器下面,那么对不起单机的线程所机制啊,不再起作用,因为synchize的它只对自身所在的同一个Java虚拟机,否则别人的Java虚拟机它管不到,所以资源类在不同的服务器之间共享了,传统的synchized或者是lock and lock就不好使了,那么同学们老眼最经典的。
01:29
V前端也是我们客户端通过N找到了我们的订单模块,我们在这儿加把锁,只是在同一个GVM以内,我们呢管用对吧。对不起,假设这是A订单为服务,这是B订单为服务,A的Java虚拟机上面加的C的锁,它是管不了B的,同理B也是管不了A的,那么在这儿我们呢,两个Java虚拟机。
02:02
他所加的锁只能对自身有效,干涉不到别人,这是第一个,第二个,可问题偏偏是多个订单模块,他们都要排着队的去。买东西,那么自然而然对应我们在这块的命令,那么是不是就是我们的set item,比如说某个商品就要减一减减number对吧?那假设100我点一下,那么现在是不是这个商品点一下卖出去一件?那重新改变它的库存设置的值是不是变成减减100,那么弟兄们都清楚是不是99了,可问题是在这堆AB,甚至还有CD多个订单模块。微服务一定是集群的,那么跑道来调用我们这个库存模块,红色这条线,这个A和这个B,谁先获得抢到库存的这个执行权限呢?所以这个就是我们right分布式所所涉及的,以及它为什么会出现那么一句话,在这块我们需要在这边。
03:10
也许是新建另外一个RA,也许是同样的一个无所谓,一句话AB,两个微服务订单模块,那么谁先去动这个库存,因为这个又是另外一个Java,虚拟机,Lock think等等,它不起作用,所以我们这折中的以及大家都会看到有种东西叫set NX,我们呢,就像是个keepper的节点,就像是我们的约定好的一个所比如说两个。那么OK,它的值假设随便,就是随便写一个好吧,那么假设就是lock的或者lock OK,随便。谁先在这儿?如果不存在我这个命令建索成功了,那么说明A先获得了优先执行减库存模块的执行权限,他去调库存模块,那么另外一个B假设执行这个命令反过来是个force,对不起,说明这个节点已经有人建成功了,我这个B只能去重设再来一次,直到我建成功为止,甚至可以是什么?这个就是A,那么假设B建成功了,这个就是B,记录下他们的请求线程ID和对应的请求流水号,OK,那么自然而然,谁库存用完了,那么咱们是不是最终需要干的活,是不是要delay delete对应的把我们这个K给删除掉,弟兄们能跟上,那么E删掉以后,说明A我用完了,B或者C或者D,你们再去弄。那么谁先抢到这个命令的执行权限,谁就得到了库存模块的扣减权限。所以这个就是。
04:50
跨Java虚拟机实现的锁操作,也就是我们分布式锁的由来,OK,好,所以呢,我们来讲明白,对于我们锁现在分为了单机版和分布式版本两种,好,那么接下来我们就要看看你要写好一个分布式锁,它所具备的条件和对应的干需。
05:14
通过前面的讲解,我们已经明白了,对于一个单机版的程序。这个只能作用于同一个加法虚拟机,那么对于我们的分布式为服务,它部署了多个节点,那么这样的话它没有办法跨界,所以我们需要分布式,所那道理都明白了,我们呢,可以用另外一个red的节点,或者同一个red节点来进行对应命令的执行操作,谁先抢到了这个执行权限,谁建立这个key,用完了给我删掉,交给其他的线程去抢夺,然后执行我们的库存扣减操作。那接下来我们的问题说需求一说谁都懂,哎,两个简单,不就两个命令吗?SNX,对吧?If not,一个exist,我们就建,如果没有存在我们就建,说明谁也没抢到,这是谁就是谁。
06:07
该轮到谁干就谁干,用完了给它关掉,相当于不就是什么建立资源、用示范资源三步有什么难的?理论上你整明白了,可下面我们的问题就来了。以前叫单机锁,现在叫分布式锁,那么请问,请思考,你觉得你要想自言从零开始写好一个靠谱的分布式所,它的充分必要条件应该有哪些?请同学们自行思考,我先暂停一下录屏,那么感谢各位同学的回复和讨论,咱们来。这个问题杨哥给大家梳理了一下,一句话,独占高可用,反思所不乱,抢可重弱。所以你真真正正要写好一把自研的锁。它的要求是蛮高的,那么接下来我们来挨个挨个过,这五个特性是你必须要满足的,你不要看你在API调用层面就是lock按洛克,哎呀,无非用的时候加把锁,中间写个业务逻辑,用完了按洛解锁不就完了吗?有什么难的?再说了,杨哥你这也说了两个命令了,有什么难的?不是这样的,写好一把锁真挺难的,有兴趣同学可以去B站上翻查一下我的GUUC2022讲AQS那张源码分析和各种对应情况,哎,但是呢,反过来也说一下,也没什么人看啊,能坚持到最后的人。
07:35
哎,不说了,好,回到这儿读这儿。首先,Only one。任何时刻只能有且仅有一个线程持有。好道理好说,你怎么保证我就要跟你抢,你如何把我弹出去?不好意思啊,有且仅有一个都懂。下面高可用来,如果是red集群环境,不能因为某一个节点挂了而出现获取锁和释放锁失败的情况,那么高并发请求下依旧要求你性能良好,充分简洁,高效可用。第三一个凡是锁也叫防死锁。
08:15
怎么办?多个请求线程也许都同时抢到了呢,因为独占和思索天生就是矛盾的,好,要杜绝。死锁是生产系统当中非常难受的故障,基本上碰到这那一定是程序业务逻辑出了问题,假设你自己用了一些自研的东西,那么必须要防止死锁怎么整,必须要有超时控制机制啊,或者撤销操作,要有个兜底的终止跳出方案。第四,一个不乱抢。一句话,现在abcd各种订单模块为服务,他们是个整体订单集群,他们现在要去调库存,反正每次只能是捡一个一个一个的减好,谁先抢到谁就去干,用完了给我抵一塔示范资源。话好说事难办,因为你如何保证不乱抢,什么意思啊,你要防止张冠李戴,不能私下按lock克了别人的锁,比如说我这儿加个锁,就这个锁的名字啊,都是同一个,可能你加把锁。
09:17
它是会有一个锁的过期时间,那么A。进来了。假设这把锁的过期时间是十秒钟,默认就是A,你进来默认情况下十秒钟怎么你也够完成这个东西了,你应该十秒钟到了,给我把它delete,给我删掉,然后B进来,哎,十秒钟以后B进来了,哎,发现没有,那么我建立我这个B,这个B用完自己的,这是顺利情况,怕就怕什么呢A。我建了一把锁,默认的过期时间是十秒钟,正常情况下A肯定十秒钟以内能够完成这个业务了,但是保不齐这个A现在今天这出事了。十秒钟没有完成,A还在这呢,但是呢,这个锁它有一个自动过期时间,十秒钟以后这把锁消失了,这个B刚才没抢到,他在外面转着呢,就像CS自学一样,这个时候突然发现,诶,这空了,那么这个时候我也建,那么默认也是十秒钟,可是过了三秒钟以后,到第13秒钟的时候,A已经忙完了自己的工作。
10:23
DELETE1扇走人了,他觉得没问题,我用的时候需要建把锁,我买我的业务逻辑13秒钟以后,虽然有点超时,但是我有没有忘了要delete,这个时候我一删不好意思啊,你A你自己的锁已经过期自动消失了,但是你现在DELETE1删这个key的时候,你把B建立的锁删完了,那这个时候B他没有耽搁,他出来的时候发现,哎,我要释放资源的时候,怎么我自己这个。B线程这个锁没了,这时候他就一脸懵逼了,这个时候极其容易出现生产问题,所以请问你如何防止张冠李戴?你不能私下按lock克别人的锁,只能自己加锁,自己释放自己约的锁,含着泪你要自己解,不能假守于他人,更不能自已去把别人的锁给干坏了,最后可重入好假设我现在调用的时候,我需要建这么一个,那么接下来不好意思啊,可能我A这个线程调了一个A方法,A方法里面调个B,这个B方法也需要获得这把锁。
11:33
锁中锁,那么这个时候对不起,你要保证同一个节点的同一个线程,如果获得锁之后,它也可以再次获得这个锁,不用再重复加锁,这个就是我们勾C里面讲的非常重要的可重入性,那么所以说同学们你要想写好一把锁,这些才是最难的,而不是说哎呀,反正我防止。不占同一时间,只能有一个人来用就行了,那么高可用呢,反思锁呢,不乱抢呢,可重入性呢,你怎么考虑?所以说这个时候前面这个面试题同学们露一眼。
12:10
你做分布式锁的时候,你需要注意哪些问题啊?你可能大部分人都能够回答锁嘛,独占性你肯定会想到,可是可用死锁,不乱抢,可重入,请问你如何做,如何考虑的,所以各位同学。跟着杨哥来,我们这个程序要写八个版本,从V1写到V8,彻彻底底把这些情况给你讲清楚,你听完以后一定内功大增,OK好,装个逼,开玩笑的闲聊,说一句那些年你双手插兜横扫一眼都找不到对手,OK,好了哈,开玩笑啊,装个逼。那么接下来,那么同学们,我们呢,就来尝尝试一下我们的分布式所,那么在这复习一个小命令。Set kv,然后ex这些命令都讲过了啊过主要是set NX,当K不存在的时候,它创建K效果等同于set NX,对吧?那么也就是说你用sat TV加一个NX,或者直接你用sat NX都可以,这个意思是你可以把它当做一个节点,一把锁,如果现在这个锁的名字啊,我们规定叫严格的ready分布式锁,有这个K了,并且这个value是具体的某一个请求线程,那是对不起,说明现在已经有人建锁了,说明人家在扣减的库存,外面的只能排队,OK好了,那么这个时候我们呢,就要清楚两把锁他到底怎么用,那么这个时候提一嘴SNX,我们说过了,你见锁成功,这把锁一般对于这样锁,你一定要保证它有一个跳出来的机制啊,你不能说永远都有效,那么差评,不好意思啊,这两个是不安全的,那么请问两条非原子性的命令,你如何把它合成一条?
13:54
那么温馨提示啊,这一章我们会重点介绍一个知识点,叫落R脚本的编写好,那么各位亲,最终我们呢,理论知识也就是要告诉大家参考勾UC当中aqs所的规范落地一下,那么也就是这些就是我参考aqs弄出来的,那么可重入考虑加R脚本抓RA的命令,一步一步的来实现我们的分布式锁,那么提前剧透。
14:23
大部分。同学都会知道,用sat NX命令来实现分布式锁,这个中小场可以用,大场绝对不可以,大产绝对不可以。明说了不可用SNX来实现分布式所,要用别的,OK,后面我们会说好。那么各位同学对于一个分布式所它的具备条件和基础知识我们就介绍到这儿,下面代码说话。了解了前面分布式所它的分类和它的这些刚需条件,那接下来我们进入到我们的编码阶段,请看案例,来,我们先做一个最简单的啊,一步一步的迭代,这是我们的第一版本,我们要求多个服务间保证同一时刻,同一时间段内同一用户只能有一个请求,那么防止关键业务出现并发攻击,比如说我们的库存超买超卖了,我甭管你这边多少个订单,为服务某一时间段只允许一个人买完一个点一下捡一个,点一下捡一个,OK。好了,那么同学们下面见mode。
15:40
Red distributed lock,二号机三号机啥情况呢?因为到最后我们要演示分布式锁是不是两台,那么所以呢,我建两个,当然同学们建好一个以后,另外一个直接拷贝就行了,因为到最后配上NX121212,要给大家演示分布式所出现超买超慢现象的一种经典案例,好,这是第一个,那么第二个我们呢,就先以我们的二号机作为突破口来。
16:10
这些我认为大家该懂的,我先提前建好,待会儿我们就写。业务逻辑service层即可,第一个建mode,我们建这么一个不说了,第二个改泡沫,那么同学们请看一眼啊,这是我们的二号机。所有的泡沫不多,对应的架报引入微服务,那么也是spring的通用模块web spring和RA,整合date RA,然后这两个是标配,然后斯瓦哥二号,因为本次啊,暂时不涉及到美被那些东西。不要引进来测试类。Book糊图工具包,OK,很简单,说白了就是主要用了spring和red整合,还有斯袜哥这两个东西过那么第三一步,那么溅末的该泡沫写亚沫煮起动叶类,我们来吧,还不是写我们的亚沫过来看。
17:09
Resources下面有这么一个东东,二号机对应的服务端口编号是7777名字,然后斯瓦哥注意这enable开启,然后对应的保证它能够成功访问啊,这个前面已经说过了,结果注射不再赘述,现在我们先连个red单击,那么对应的。哪个?零号机器自己的IP端口号,然后密码这些不说了,那么在接下来那么主启动内,同学们,这些无关大局的我们提前写好,待会儿直接上业务逻辑OK吧,好了。那接下来我们的业务类主要就是丝袜哥config和red config,这个呢,同学们在前面也见过多次,对于我们的袜哥,大家请看这是不是。
18:01
点开斯瓦哥2ENABLE,目前依赖注入在我们的配置里面,这个是什么开启的状态?好吧,如果你上生产了,不想用斯瓦哥了,把那块一关闭,这块是个force。王活,做一个开关介入,那对应的我们的包名用你自己的,好,这是我们的四二哥,那么接下来red figure,那么也就是我们的red complete对应的这些阶层序列化对应的配置O了,那么同学们最后一步是不是只剩下我们的service和CTR了?来看一下本次我们要做的操作是register分布式组的测试,然后CTRLL调service,那么也是inventorory是库存的意思啊,那么库存调用我们的库存service啊,卖。调用这个这样方法,库存扣减一次慢一个点一下减一个,点一下减一个,就这么简单,好吧,咱们先把基础版的,那么大家同同学们请看这个叫什么贝斯版的程序先铺建好,然后我们一点点在上面加分布式所相关的要求和概念,那么接下来同学们我们就来看看怎么写这个service呢?来,我们首先第一版的程序。
19:14
Service啊,要调用red temp,那么我们这啊用的是另外一个,也是工作中常用的叫string red,不废话,我一叠这个类击成一神。这个是不是见过很多了,那么所以说他们两个无非就是list接口和什么list落地实现类的一个关系,那么我们用string子类是不是一般要比他老爹要能干一些,功能要多一些,好吧,其实都一样啊,只是给大家呢尝个鲜,用个新的,那么再来这个是呢,我们的端口号,为什么?因为到后面我们上两个的时候,NS连上这两个,看端口号,比如说这个叫7777,就是A服务,这个叫8888,就是B服务,好吧,我们先把7777写完了,待会把二号机的程序全部拷贝进三号机,改改名字就行了。好,那么同学们controltr了,要service,因为这些都很简单啊,节约时间,怕同学们看吐了。那么所以说呢,重点我们写其他这些。
20:12
重复的节约步骤好了,这个时候一点一下少一个,点一下少一个,弟兄们是不是有点像我们什么卖票的程序,点一下减一张票,点一下减一张票,直到库存为零,所以我们这儿先约定好,我们设置INVENT001,比如说库存001什么意思,北京啊,比如说京东北京仓库,那么这个时候库存。那么假设001可以是地址,也可以是某一个,比如说库存里面001代表是毛衣,哎,或者是手机有100个,那么现在get这个是我们的key有多少100个,那么待会是不是通过我们的甲板为服务程序点一下,在这就少一个,然后我们这的数字是不是应该是99啊,好,那么同学们这个该怎么写呢?来,不废话。要么你这加个SNCH,因为我们植入主题了啊,学过多线程了,点一下少一个,点一下少一个,对于这样的I加加I减减100%是线程不安全的,所以我们private对吧,那么lock lock等于new re lock,这个不再废话,那接下来我们呢,就来看try lock lock lock对吧?这个呢,就是我们定义的要返回的这个呢,是我们的message,中间是这个,这个是不是写我们的业务逻辑来吧,那么主要该怎么写呢?其实呢不难,就三步,第一个查询。
21:35
库存信息对吧?那我们在这是不是我们的STEM OPS for value类型的,那么来弟兄们,我们get谁呀?那么在这块啊,我呢,把这个key拷出来,我这偷个懒啊,上面我就不再定义什么常量啊,反正这个你都知道什么意思,那么来在这块是不是应该得到我们的库存的返回结果值对吧?那么来看看这个库存它有没有,那么如果有的话,你要搞清楚。
22:10
我们现在在里面这个type,如果我们这个K啥类型,是不是死猪类型,那么你在做数字的时候是不是要把它转换成in特弦,对吧?要做一个类型转换,那么接下来这个就是判断库存是否足够,那么来弟兄们integer,那么inventory。那么这个时候。那就等于这个raise out,对吧,我们先获得这个现在库存有多少,那么这个raise out就麻烦了,第一个它有可能没有,就根本没有这个K,所以这个raise out它有可能是等于none,如果等于none的话,我们这个库存值是多少,就是零听懂,那么否则的话来in.pass in,那么out,将其ju类型的数字转换给我们的inventory number没问题吧?好,第三一个,那么来进行什么扣减库存,每次减少一个商品,好吧,那么该怎么扣减呢?那么所以说我们的衣服。
23:33
Inventory number要大于零对吧?我们现在先查查库存剩余量,那么先,然后呢,从死猪类型转换成数字类型,假设这个数字inventory。大于我们的零,说明有库存,有库存是不是才能扣减啊,对吧,所以说在这。string.open for点干嘛呢?Set点一下就要重新少一个,这么说听懂了吗?那么来吧。
24:06
这个时候我们搁到这,我们的T就是这个001,那我现在只要是大于零,我直行的,什么直行的是不是点一下就少一个,那么所以说strange value of就要把这个整形的再转换回去来,先把它剪了再转换回去,这一波弟兄们能不能听到,先去查查库存有几个不能为纳。对吧,也就一定要大于零,那么大于零那说明什么?我点一下我是不是要减一个我的库存就要从比如说从100变成99,那么得到这个99以后,我要是不是要重新设置值回去,OK,所以我们在这儿return。Message就等于什么,是不是就是成功卖出一个商品,OK,那么库存剩余多少呢?那么接下来这块是不是要加入我们的inventory number,这波弟兄们没问题吧?那接下来后台打印出来,那来一个在这块是不是就是我们的空格以后服务端口号,那么接下来这是不是有一个东西叫破OK搞定,那假如说没有这个库存了呢?那对不起,这个message就等于商品卖完了。
25:44
OK一样的,那如果说这个else的话呢,你也可以把它写在这儿,或者不写也可以,对吧,我们在最后这给他返回也成,那最终弟兄们,我们呢,返回我们的return message。
26:05
把这块也直接粘贴完活,OK,这个呢就是我们的service,好,那接下来微服务成功启动,来试试我们的丝袜哥,那么现在我们的库存是一百点一下减一个,我们这个里面的库存是不是只应该剩99个了?好吧,那么来同学们,我们呢,启动一下我们的微服务。好,我先暂停一下录屏,同学微服务成功启动,哎,那找到我们的测试地址,宋二哥来大家请看,扣减库存一次卖一个点一下,好同学们请看我们的后台成功卖出去了一个商品,也就是第100号商品卖出去库存剩余多少?99,现在我调的是谁7777这个为服务测试通过,那么同学们lo get是不是99个没问题吧欧了,所以说接下来那么弟兄们我们呢,就会看得出现在我们最经典的规规矩矩的look UN look没问题吧,或者你这加synchize的都可以啊,那么这个就是我们在单机版的类似于卖票一个程序加锁假设。
27:15
现在一点点来没有B这块东西对吧,那么只有一个A,就是7777,那么避免大家都去强,所以在自身是不是加了个gbm。也就是说自身GM的锁S或lock洛啊,现在我们不扯另外一套服务,那所以说这样可以保证像卖票一样的通过访问扣减库存,打完收工,OK,那么接下来我们叫手写分布式索喽,那么一步一步来,那么请大家来找长案,来看看杨哥所写的程序有哪些bug,我们一步一步完善好,那么这个best。基础的这个所谓万丈高楼平地起,一切承担靠地基,现在我们的贝斯案例7777打完收购。
28:07
通过上一讲,我们已经完成了我们的贝斯第一版的基础程序,听好,写到这儿,我们没有任何分布式锁的东西添加,只是一个最基本的样板程序,在它这个基础上面来进行我们分布式锁的添加,我们现在是不是添加了一个单机版的re enlo和unlo,没问题吧,那么在这个的基础上面我们来来添加我们。分布式锁的功能。结合前面我们所讲的这些充分必要条件,一点一点的给大家演示啊,我们的程序如何通过资源的手段点滴完善我们的分布式锁,加强我们程序的内功,实际工作当中,你可能不会去用这个自研的分布式锁,当然可以用啊,也许你会去用red sun,但是对于增强各位同学的内功,我认为这一节的讲解和分析是非常非常重要的。因为。
29:09
练武不练功到了一场空,真真正正到最后用也是用red sun rock and rock就完了,可是它底层的原理是些什么东西,那么同学们务必知晓好了,那么接下来在这个的基础上我们一点点加,大家呢,一起来找茬好了,开工,那么上面的测试弟兄们7777已经成功了,接下来我们要慢慢的配置成这个案例,对吧?最经典的那么是不是也要两份程序结合NX来完成我们的库存减少啊好了,那么同学们。请看一眼第11.0版的程序,我们已经完成初始化版本简单添加,我们呢,手工点击这个点一下,少一个点一少一个测试通过我们将7777的业务逻辑代码原样拷贝到8888,节约大家时间,拷贝这个动作我课间已经完成,二号机的全部程序如法炮制,原模原样的拷贝进了三号机,唯一的区别就这它的端口号叫88884,瓦哥的访问也叫8888 OK,好,那么在这块。
30:28
我们呢,一样的配置过,那为什么要这么干呢?首先啊请先大家呢,先看好啊,这是7777对应的service程序,这是8888对应的service程序,首先以部署以后七七七七八八八八两台为服务,两个gbm,所以二十五行这是7777。加的锁,同理30行,这是8888加的锁,两个都加锁了对吧?好,单起板的没问题过接下来同学们N分布式微服务架构,一句话,实际工作中我们去部署同样的一个订单模块,库存模块,扣减模块,物流绝对不可能是个单机版,所以呢,我们呢。
31:22
升级为2.0版的程序分布式部署。那么单机锁。绝对会出现超慢现象,所以我们要引入分布式所。一句话,弟兄们,实际工作中大家都清楚,你的请求一定是先达到NX,由N做反向代理和负载均衡,77778888787878。好,再强调一遍,任何一个单机版的程序,我可是都加的锁的。那么下面我的问题来了,大家觉得单机版的时候这个肯定管得住,那么到了我们分布式版本以后,图面了这个锁会不会管得住?那杨哥,什么叫超卖现象?好,那开高就要加上我们的NX了,首先NX来配置负载均衡和反向代理,注意对NX的知识默认到高阶偏你已经懂了,有问题的同学可以去上硅谷官网上去查看,有其他老师录制的engines基础入门篇,好吧,那么在这儿你呢?跟着杨哥配也可以。
32:42
第一个很简单,按inx命令的地址和配置的地址,Inx的命令,那么就是个inx,那么它的配置就是con配置文件夹下面老规矩,凡是配置目录先把出厂默认那个给我拷贝一份留作保存,我用的默认user local,相当于我们Windows的program files的这个文件夹好,那么启动命令在这个这个B目录夹下面,点IN1启动,那么你是这个时候访问inx的目录地址,默认端口号是八零,浏览器看到welcome的页面搞定,那么这些我默认你就懂了,我就不再废话,那么接下来跟我们有关系的本次案例就是在。
33:26
康目录下面配置文件N康复新增反向代理和负载均衡,那么来同学们。我们呢?找到我们的,在当前路径下面找到我们的N。看配置文件,注意请把它backup保存一份,然后修改它vm engines,那么来,弟兄们。搁到这感谢什么呢?首先我把那个欢迎界面就是welcome engines80那个注掉了,那么被反向代里的关键是不是叫xy proxy_pass那么这个时候http my engines,那么proxy代理找谁?是不是my engines,那么你的server engines要去访问两台谁一号什么通道,就是我部署在idea里面,我Windows的IP,那么来同学们这个时候是不是我们的77778888权重1:1,就是七一次八一次,七一次八一次,那么这个proxy代理的话,这个就是这个,请看http my engines是不是就是这的upstream my engines反向代理弟兄们,OK,好,我们提前给大家配好,因为这些都是节约时间啊。N进X的东西过,那么保存退出以后,兄弟们接下来复习一下。
34:54
基本命令在这个下面点N-s stop,这是关闭我们N,那么我们接下来我们要启动,如果你启动的时候就一定要注意,你要告诉NS啊,我要求你去找这个路径下面的。
35:12
Engines config,因为enginex的启动像我们的red一样,是可以指定我们的配置文件的,你指定哪一个,我就按照你配置文件的内容启动哪一个以什么样的方式启动,OK,所以给我指定路径,指定主人,你要求我按照哪一个操作手册的配置来进行启动,所以要求指定配置,那么来,同学们。Log沿,那么就是这个路径下面给我指定杠C,这个参数有点像我们的路由参数啊,所以呢,在这块,那么同学们请到user local enginesbb目录下面啊,那么好,大家请看在这个路径下面是不是有一个。
36:00
N的命令,好了,要求这个命令去。杠C指定你要让我按照哪个启动这个来启动,好各位同学粘贴搞定没有没有消息就是好消息,杠出现grape engines弟兄们搞定后台启动了吧,好了过那么当然如果你重新配置了,你需要重启也是在这个路径下面,杠N点杠斜杠N-S一个是stop,停止reload重启好配置就这么一点东西。Proxy_pass反向代理好,那么这个就是配置了我们的NX,那么来接下来我们2.0版本的代码修改,是不是叫启动两个微服务了,第一个七七,第二个8888,然后注意以前是直接访问我们的微服务,现在是通过NX访问,那么你的这个Linux服务器的IP反向代理加负载均衡啥情况呢?我们可以看到这个效果,一边一个默认是不是叫轮询,注意这个IP就不是localho了,185什么意思啊?
37:17
这个185这段IP是你Linux上面抓inx,你自己的服务器地址,不一定跟我一样,请同学们务必认清楚这一点,别到时候你直接扎脑图一张,不对,185是我,不是你的Linux服务器IP,好,那么同学们。Engines已经启动,那么接下来我们的7777将它启动,然后呢,我们的8888将它启动,回到我们的red里面,Set,零零幺一百,GET001100 OK,好。那等它启动了以后,那么同学们,我们呢,简单的呢,来看一眼OK吧。
38:06
好,就拿着我们的IP地址搞到这儿,慢慢的靠近我们这个模型,那么我们现在一反问同学们,请看点一下第100号。卖出去了,还剩99个,现在提供这个服务的是7777再来一下。点一下99号卖出去了,还剩98个,现在提供这个服务的是8888,好,那么我们点叠叠叠叠叠。没问题吧,现在是不是岁月静好吧?那么搁到这我们可以看到77773579奇数,88882468偶数挺和谐吧,没有任何问题吧?所以各位同学,我们现在写程序貌似到这儿都OK吧,好,那么同学们可以得到。
39:03
上面纯手工验证是完全OK的,下面我们呢模拟一下高并发,那么也请同学们想想,我们这个程序在高并发下面,你觉得会不会有问题?通过前面的演示和验证,我们纯手工点是OK的,那么我的问题是。这个一定OK吗?那么高并发下面我们会出现问题吗?可能有同学会说这不点了吗?刚才挺爽的,点一下少一个,点一下少一个对吧,在这儿来我们点快一点,没出什么问题啊。各位同学,你的手速还是不够,那么接下来咱们呢,高频发模拟工具解密打开走一圈,来看看在当前这个程序下面,它会出现哪些问题。
40:01
第一个。先恢复我们的100个O吧,好,第二个打开我们的解密塔,高频发的测试工具。至于说这个工具怎么用,杨哥在给大家讲spring cloud的时候详细说过,好吧,不再废话。一。请查看对吧?那么你在这测试计划ADD添加一个thad group会吧,有些人说看不懂,看不懂的option选项,这是不是有个语言选择,这有音学,这是不是有简体中文。秒懂,OK,好,那么在这儿形成数。我们这几个100个,所以我这100个几秒,一秒循环次数几次啊,一次一秒钟100个线程砸过去,好第二个我们添加这个取按器HTP请求,那么来这个呢,是我们Linux服务器地址,这一定要搞懂名称或什么IP地址啊,所以我们这只留下NX所安装到的那台服务器的地址啊。
41:17
185机器端口号N端口号是不是八零,那么对于这个地址八零端口做什么请求get请求查询嘛,对吧?路径那么来同学们他自己会去拼装。我们只留下我们rest这个地址,就是CTRL啊编写的这个地址,弟兄们,这波没什么问题吧,有点类似于这个啊,就这货,那么你要告诉人家我去访问哪一个地址对吧?好,这是CTRL的这个地址,也就是我们这个访问地,好,那么同学们接下来万事俱备,只欠点击,但是还有一步重要的工作,在HC请求上再添加。我们呢?
42:01
在这块啊。嗯,哎呀,找不到。我还是习惯看英文的哈,稍等。选项语言英语好,那么在这块的话呢,那么弟兄们,我们这。Aggregate report什么意思啊?聚合报告,那么就来看看杨哥。你一秒钟干出去100个请求线程,那么在这儿样本数应该是100,平均访问居中的90%,什么情况?那么最终看看错误率,如果你这次反问乘高,那么这是不是应该是零?OK,没有错误对吧?最重要的我们前面讲过。这个是不是叫吞吐量,这个数字是不是越高越好对吧?说明你的系统越牛逼,那么接下来同学们不废话,来777888啦,后台清空日志。这个100好了。
43:01
开光,那么来进行一下保存。来。同学们跑也。看一眼,这开始跑着了,好啪啦啪啦的也出来了,那么这个可就是很快了,对不对。接下来同学们看一下,一回车几十二。我明明选的是100个,这个时候最终的答案是不是应该是零才正确啊?那么说明什么?我们的程序你认为加了洛and look或者think,在单机版的情况下,现在变成分布式去反问,100%会出错,那么这个时候同学们请搂一眼啊同学们。一般前面我们见过8888是偶数,99,奇数怎么跳出来了好。同学们请看99在7777卖过一次,在8888又卖过一次,看到没有,所以说正常情况下,你手速点的时候是不是应该EGOEGEG哦,现在对不起,99这个在8888出现过一次,7777出现过一次。
44:14
典型的电商项目里面的超卖,这个时候一笔单子两笔数据,货不对版,暂时不相符,恭喜你兄弟摊上事了,说定级P几级生产事故造成了公司止损,OK,那么这个同学们思考一下。我们这的笔记啊,是这个被卖出了两次,出现了超慢现象,那么这些请求啊该怎么配的,那么弟兄们按照这配IP,这这个我们都演示过好吧,笔记咱们来过,为什么会有这个bug。大家思考一下,我暂停一下录屏,为什么加了SYNCH或者lock还是没有控制住呢?来,弟兄们,请大家注意。
45:02
单机环境下面我们是可以使用这个控制的,没有任何问题。但是分布式系统当中,因为竞争的线程可能不在同一个节点,也就是说不在同一个Java虚拟机当中。所以需要让所有进程都能访问到的所来实现。也即我们的right分布式锁,说白了就是这张图,弟兄们都清楚啊,哎哎哎哎,这有个Java虚拟机对不对,不好意思啊。这个Java虚拟机其实而言,它对应的是7777,那么我只可能管我7777相关的兄弟和数质那么一样,8888也只能管自己的,所以七管不到八,八管不到七,在这儿他们两个只能保证同一时间自己送出去一个,还是挤红色的这根线,所以库存模块出现了超慢,同样的东西被卖了两次。
46:04
接下来按照我们的笔记,需要一个让所有进程都能访问的所来实现。不好意思了,回到我们的这儿,是不是代表77778888,你们不能只凭借自己的单机锁去访问库存模块,必须在这儿这条线过来。谁先在Rex上面获得这把分布式锁,谁才能去访问库存模块,所以不同的进程到GVM层面,它这个锁就不管用了,我们只能利用第三方的一个组件来获取锁,如果没有获取到锁,要么阻塞,要么重设或者超时等待。OK,你必须获得锁以后才能进行你想要的后续操作。所以加了这个在分布式下面毫无意义,因为它是单机版的。基于此,我们分布式所出现,因为现在所有的微服务程序基本上都是多个N配置,N集群,后面做反向代理和负载均衡。
47:07
那么你的单机锁。是用不了的,接下来这个就是我们分布式锁为什么要出现的意义,那么它能干什么?是不是要跨进程跨服务解决超慢,防止缓存击穿等等等等一系列动作都有它OK,所以兄弟们怎么解决上right分布式锁set NX。那么也就是这。其命令对分布式锁支持友好,借助set命令即可以实现加锁处理,现在大家都来抢,没有人在这上面建了,谁先建立谁就抢到了red分布式所去扣减库存,用完了示范资源,Delete给下一个请求过来,如法炮制,建立干活示范三步完成,OK那么来对于write分布式所set相关的官网命令,弟兄们就在这儿,有兴趣的同学可以看一眼。好,那么接下来弟兄们。
48:08
我们上了N的2.0版的代码,到此结束,说明什么?我们的单机锁是没有办法搞定我们的right分布式锁的。
我来说两句