00:00
好,首先呢,来看这个代码该怎么去实现我们的分布式错,那么撸R脚本写好之后呢,那代码实现起来就比较简单了,因为大部分的业务判断咱都在R脚本里面已经实现了。好,代码怎么写,我们可以先把这个方法给它备份一下啊,拷背一份让它放在上面,然后把这个方法让它改成六,然后回到我们这个备份方法里面去,咱们这个方法呢,给它啊去掉啊,加锁的地方给它去掉,那么解锁的地方也给它去掉啊,重新还原回最初的那个样子。那还原回去之后呢,那我们希望啊,来去前面加锁,那么后面呢,来去解锁这样子。好,那么并且呢,要保证我们的可重入性。那么这个代码呢,还是比较麻烦的啊,加锁和解锁代码。那咱这里呢,可以封装成一个工具类,那这样一呢,通过这个工具类就可以玩我们的分布式索了。那我们来去封装一下来,你有一个类啊,这个类呢,给它放在lock这个包下面,那命名为tree beauty的lock啊,再给它加一个red,因为它将来呢,还有my circle,还有key的分布式数。
01:17
好,然后呢是OK。创建好这个类之后啊,那这个类呢,咱可以让去实现一个接口,那我们的re lock,我们知道它是实现了一个接口的哈,人称lock实现什么接口的呢?它实现了一个lock接口。啊,这是GUUC里面的lock下面的lock接口啊,Lock接口了。那么它是基于iqs来去实现的啊,那我们呢,要基于啊咱的RA那么来去实现。咱们也可以实现这个lock接口啊啊标准化开发。好,那么回到我们的BU啊,Beauty的lock里面去,我们也去实现一个lock接口,好,这也是GUUC下面的log下面的log接口。
02:09
然后呢,我们去实现它里面的抽象方法,哎,它里面呢,有这么多的抽象方法。好,我们来去,呃,仔细去看一下每个方法哈。那么这个方法呢呢,加速的方法有这个lock方法,有try lock方法,以及呢吹lo带参数的方法啊,一共这三个方法啊。然后解锁的有一个方法叫unlock方法,那主要是这四个方法,那么其他方法呢,咱就不去看了啊,咱不是不能实现,能实现只是呢,咱没有必要去实现,我们把核心方法给他实现一下。咱主要去实现这个加锁和解锁方法,咱么不实验的方法给它收起来。那么加锁方法呀,其实实验方式都是一样的。哎,我们最终去实现哪个就可以了呢,我们最终就实现这个带参数这个方法就可以了。
03:01
只要我这个方法实现的,那么这个不带参数的,那么好不好写呢,很好写,你就直接调v.lock。那么如果我没有设置过期时间,哎,咱可以给你锁呀,设置一个过期时间的啊,如果没有设置过期过期时间。那我们可以写一个,写一个负一的这个位置。那现在我可以判断,如果是负一的情况下。那我们可以去。我们可以使用默认的过期时间,比如30秒的过期时间。啊,这样的。好,那么呃,单位啊,我们可以来一个呃,Unit time unit six。秒为单位。好,这个地方呢,我们应该是来一个负一啊,这过去时点那么有异常,我们可以来一个KK。处理一下。那么有异常的情况下,来一个force代表获取锁失败了,尝试加锁失败了。
04:05
然后呢,我们再回到这个lock方法里面去,那lock方法它可以调我们这个维S点吹lock这个午餐的这个方法好,那么这样呢,呃,我们这个方法结构啊就出来了,那lock呢,是基于trylo的一个时间的,那trylo呢,又基于咱们这个trylo带参数这个方法的一个时间的。那最终我只要去实现这个加锁方法就可以了,好,那么这的话就是咱最终要实现的。加锁方法,我只要把这个方法实现了,那么另外两个方法自然而然的就已经实现了,因为它是利用了咱们这个方法。好,那么然后再回到这个unlock里面去,那么unlock呢,这是我们的解锁方法啊,但只有一个啊,这是解锁方法,那就比较简单了呀,我们就只要实现这一个方案就可以了解锁,然后呢。好,那我们来看一下啊呃,加锁呢,该怎么去加呢?好,我们肯定要通过咱们的撸R脚本来加锁。
05:04
那咱这里呢,可以定义一个啊string类型的啊,克葡萄乱脚本啊脚本字五块。这个脚本字符串呢,咱可以从我们之前写好的这个脚本里面来进行拷贝啊,从前拷贝到最后这个位置,那么copy定好之后呢,给它放到咱们这个script里面去啊。好,这样呢就可以了,当然呢,你为了方便阅读,你可以换一下行,但你不换行,那完全也没啥问题啊,那我们这里的话呢,为了方便阅读或者观看,咱可以换一下行。如果所不存在啊,或者呢,这是我的锁。那咱就可以怎么样呢?满足这个条件啊,我们就可以去加锁,或者进行可重入啊,进行重入,然后呢,再重置过期时间啊,重置完过期时间之后呀,我们获取锁成功平一个一。然后呢,否则我们就加锁失败,变成一个零,那最后呢是R脚本结束。
06:06
啊,那么然后呢,我们再去看这个R脚本去执行啊,那么执行我们就需要ready comp来执行R脚本。那ready tempet咱就需要注入进来哈,那就注入一个ready,然temp咱需要那个string,然write at,好,那么把它呢,呃,给注入进来,那么你这里要注入进来。首先一定要确保这个类啊,这个类对应的对象要在死命容器里面才可以,那你得要来一个抗框定注解。因为我们这个类啊,它既不是CTR了,也不是service,也不是持久层,所以大要使用这个抗这个组解啊,输入到四分容器。啊,只有它在死SPA容器里面,那么咱们这个string ready碳排的才能注入进来哈,如果它在SPA容器里面,它肯定在SPA容器里面,那而我们这个beauty的ready knock不在死SPA容器里面,它能注入进来吗?
07:06
注入不进来哈。啊,所以呢,我们加了一个component注解。要加这个入点才可以。那么这样的话呢,将来呀,我在代码里面,我要使用这个分组,那我就可以还能来一个rabbit,可能是第一次可以beauty的red lock。然distribu red lock和ultra,那你可以使用我们这个分步骤所为加锁解锁了哈。那么这样玩呢,其实不够好。啊,因为呢,如果我需要的分布式所的话,那我就要注入分布式所对一项,那如果我要需要呃,Key的分布式所呢。那还得有K的分布式对象,那我可能还有MY等等。那要注重不同的对象。那很麻烦。所以呢,咱可以借助借助于那个工厂啊,工厂模式。来给他设计一个工厂,那么注入呢?我将于注入工厂就可以了。通过工厂我可以获取red,也可以获取key po。
08:08
那比如说呢,我就可以给这个lock来去设计一个工厂啊,那这样的叫beauty的lock。然后那分布式所客户端它是一个工厂类啊,那么这工厂类咱就需要那个工厂方法,那我们这里呢,你可以提供一个工厂方法,反问词呢,是第beauty的ready lock,那get ready block啊获取ready分音布是锁的一个方法。那你可以去另一个,然后第beauty的redlo啊这个玩意。那么我可以呢?把这个玩意注入到四零容器。啊,注到资本金,那我这个ready分布式所呀,那我就不用再去注到资容积了。
09:00
我们就可以把它给啊去掉,把那个注解,将来我使用的时候注的是谁呢?住的是distributed lock clean。啊,住这个工厂就行了。好,我们要注入的将在我们使用的时候注入的是BU red lock。啊,不是那个克啊,D beauty啊,Log克就是这个工厂啊,D beauty的log克的工厂。那么工厂有了之后,那你想获取任何锁都可以获取了,比如说呢,我想通过这个工厂,那就获取ready的分布式数,哎,那这样你可以获取到ready分步骤锁了呀,来一个ready,点上lo就可以加锁了。那么将来呢,咱在finally里面啊,为了保证,为了确保我们能够解锁啊,在finally里面我就可以去red lock.unlock给解锁了。来这样就可以了呀,那么使用起来就很方便啊,很方便。
10:04
好,那我们来看一下,那还有呢,这个锁的名称。一定要允许用户来指定。啊,就是那个里面那个key,我们一定要允许让用户来指令啊。啊,咱比如说咱可从所谓有外层的这个K。你看这个内层的这个field的对吧,啊F的以及呢,最里面这个value。我们是以所的名称作为K,那咱本质是对他的一个增强啊。然后以UUID。以UID作为这个内层的这个K啊,然后呢,以我们的重入次数,比如入了三次作为value放进去的。那本质是对他的一个争强。那不同的地方,那大锁可能可能不一样,锁的名称可能不一样。所以这个外层的K,咱就要允许让用户,让使用者的一指定指定锁的名称。
11:00
如果都叫lock的话,那相互之间就都锁住了啊。那么UID呢?是每个请求都不一样。每个品都不一样,咱可以在内部呢,可以生成。啊UID的话内部再生成就可以了,那重录次数看你加了几次锁,我来进行累加就行了啊,那唯一需要指定的就是这个。咱校区治病。啊,那我们啊回过头来,那么在我们哪个方法里面可以指定锁的名称呢?因为这个lock方法。哎,是来继承字啊,是来自于这个lock接口的啊,我们给它里面去扩展一个参数吗。能在这log方法里面扩展一个参数吧,不能因为在这个log接口里面,这个log方法就没有参数,所以呢,你肯定不能在这个log方法里面来去扩展。但你咱不想改变这个lock方法的使用啊,那只能在这个里面的一个指定。来谈这个。老克说。Log锁的名称,那咱先定义一个string类型的lock on name,来我这里直接传一个log string类型的log锁名称就行了。
12:05
那么也就是说呢,咱这个工厂里面,我们这个get ready lock可以允许去指定所名称来一个lock name,然后再传给谁呢?传给我们的这个分布式所。然后再传给他,那咱只能通过构造法来遗传啊。好,那我们这里的话呢,可以来一个呃,Lock name来产给这个red的这个分布之所啊,那我这个里面呢。就需要有一个带lock锁的一个构造方法。那么定义一个构造方法。那来一个嗯,Public,然后呢是string,然后lock,呃,Name这样的一个玩意儿,那再来一个构造法啊,那这构导法呢,我们啊可以有这两个参数啊。因为我现在这个red这个分配热所,它已经不在死频容器里面了。那你通过主外能注入进来吗?也注入不进来了。
13:02
也注入不进来了,只有谁能注入进来呢?只有我们这个分布式锁的工厂可以注入进来,这肯定的工厂可以注入进来。它呢在密容器里面,所以它这个里面呢,是可以注入这个string啊,Ready碳ready碳特的啊,是可以注入的啊,来一个奥的。那么在我们。这个工厂方法里面,那我就要把这个ready comp也要传递给我这个ready分布式所了。要传递过去,我需要把这个传递过去,但是name呢,也需要传递过去。而我现在呢,已经给他创建了一个。这个构造方法了,那当然可以传了。那于是呢,我就把咱们这个ready唱,还有这个拉锁的名称都给他传过去了。那么弹过去之后呢,哎,咱现在呢,呃,我们这个ready分析师所这个对象里面,这个类里面就有ready坦白的了,啊,也有这个lock的名称了。
14:04
那我们接下来呢?来完成我们这个加锁方法。咱应该是this似点ready摊点上你有一个包的ready script,把script给它放进去,那反离值类型咱是一和零在多少脚本里面,那在Java里面对应的就是出和false。那你可以来一个布点上class。Class,然后呢,我们就需要这个key点上的a list。那么然后这里的话呢,呃,我们要去指定咱这个锁的名称啊,这是锁的名称,K列表是K列表,那么K列表啊,我们只有一个啊K啊。这也可以就是lot所的名称了。那的名称咱之前已经谈过来了,就这个lock name给它放进去,将来在我们的red里面就是以它作为外层的key。
15:00
然后以UUID作为内存的T,那UID也需要,也需要它呀,也需要UID呀。那么U怎么办呢?我们还需要有个ID,也就是说在这个里面。那么我们就需要一个private,那咱这里呢,最好是一个private private,然后呢是string好UID,那UID怎么办。那原ID呢?哎,老我老师我初始化这个非布式索的时候,我也给他初始化一个UID不就行了吗。那每次我去执行这个get ready ready lock的时候。那么就会执行我们这个构造动法。然后呢,我就可以重新生成一个UID了。那就可以重新去生成一个UID了,哎,咱好像可以这样子,我们来试试啊this.uid,那等于UU id.round id.string你每次来获取锁的时候,我就会给当前线程,相当于给当前线程。
16:03
生成的一个UID。然后呢,在这里呢,我就可以去使用这个UUID啊。那么还有呢,呃,二个列表吧,还有一个呢是过期时间。那么过期时间,那我们这里呢,如果你使用这段话来加锁的,那你可以指定一个过期时间啊。OK,那你也可能是通过咱们这个方法来加锁的,就没有一知病。那么如果你指定了通过这个方来去加锁的啊,你指定了,咱们要用你指定的过期时间。哎,那么咱这的话呢,就要去判断一下了,来一个if判断。判断这个time。啊,这个time,这个time呢,如果。不等于那么负一。啊,如果等于负一的话,咱可以呢,搞一个XP过期时间定一个啊呃,来一个long的型的嘛,然是XK啊这过期时间,那过去时间咱给他写死啊,比如末咱是三一乘秒。
17:07
啊,30秒的过去时间。如果你不等于负一,等于负一不就使用默认的过期时间就可以了。那如果不等于负一,说明你指定了国际时间。那我们就可以使用好呢,使用。咱们这个,呃,你指你指定那个国际时间啊。如果等于负一的话,就使用的呀,如果不等于负一,我就使用你指定的。啊,来一个啊this.xq等于那是unit点上,然后to ss把这个time呢给它放进去。啊,如果你等于这个我要转换成以秒为单位啊,咱们过去时间是以秒为单位的,那么这个单位呢,有可能是任意单位的过去时间啊,大家把这个时间转换成以秒为单位的时间,要复复制给这个XP。
18:00
好,那么然后在这里啊,我们可以设置这个XP过去时间了。咱一定要是必得死类型的啊。来个点to string,好,咱是一个基本类型的一个LA,现在我们要去使用它,使用这个string,写上value of,然后是exp,那为什么这个地方必须是string类型的呢?因为咱使用的是string ready temp是不是这个东西,这个咱必须是字符串类型的,否则你这过期时间呢,它会报错。你可以试一下,那我们在课堂上咱就不试了啊。好,那么在这个地方啊,我们可以去判断一下,来个well well判断来个循环重试,对吧?啊,如果我霍金所失败了。那么这个地方应该返回的是一个。是一个false。是一个false。那我们就可以进行重试。啊,来一个瑞的啊,瑞的循环重试呀,让他睡一会再进行重试,比如说睡一个呃,50毫秒能起来重试一下。
19:09
那么这个地方呢,它没有报异常,那就不需要出开机了,因为这个方法它本身就有抛物异常对吧?啊,那么这就不用去处理了。好,那么如果最终呃,我这个循环T出来了,说明还能说明咱锁就获取到了,那这个地方咱可以返回一个数获取锁成功。好,那么来加锁呢,我们这样就可以了啊。然后呢,还有这个解锁。解锁的写法呀,跟加速呢有点类似,那咱还是有一个脚本来一个string。啊,让克re,等于我们解锁的落脚本,咱们也给它拷贝过了啊,就这个嘛。然后呢,Copy到。咱们的代码这个地方去。然后我们可以稍微调整一下啊啊if判断判断呢,你自己的锁是不是你自己的锁,或者你自己的锁是否存在。
20:03
如果你自己的锁都不存在,那说明你在恶意释放锁,等于NRL,那么a c if,如果你的所存在,我们就直接减一操作。哎,减一过之后呢,是不是等于零。如果等于零。那我们就可以去释放锁了,那么否则我们检一过之后呢,就可以了啊,啥都不用干。好,那么最后呢,咱的撸标本结束。结束过之后呢,咱可以S点啊,Ready碳排点上cut,那么另一个嗯,Default ready script把给它放进去,那放进去之后呢,那咱这里呢,可以注意这个地方千万不要使用布尔类型的啊。为什么不要使用布尔类型的,因为如果你使用布尔类型的话,那么咱这个标识V啊,其实是有三个标识位的啊。有三个表示位,一个是呃,NLN的话,你想的是是那个空在Java里面对不对啊,是空啊。
21:05
那么然后呢,还有一个呢,是一释放所成功,那应该是一标识位。如果出来了一次啊,代表的是零对吧,但是零来标示的啊,如果你使用布尔类型。来去拿这个瓦硝根的反应值的话,会出现什么情况呢。好,注意啊,零它在布尔里面是false。那么这个NRL啊,在布尔里面,他也认为是false。那你就区分不出到底是恶意声浪锁还是出了一次了?太顺了一次了。那一呢,一就是出完了呀,一就出。那么就不好判断了。好,所以呢,咱这呢不要去使用波,那咱要使用啥呢,使用。这个给他使用一个long类型的,那么使用long类型它就有三个标志位,那么这个NRL的话呢,在long里面呢,是一个long啊,然后这个零呢就是零,那么一呢就是一。
22:02
啊,这样子好,那我们看这个代码。呃,然后咱要去设置我们K列表和这个二格列表啊,K列表呢,只有一个元素是log锁的名称,那么还有呢,二列表呢,只有一个UID,那这写法就很简单了啊,来一个a race给掉as the list。好,把我们这个log的名称给它放进去。那么还需要。那咱们这个UID啊,这个玩意儿好,那我么这样呢,就设置好了呀,最终返回的咱可以来一个flag,咱可以判断了啊if flag等于那代表啥呢?代表你在恶意释放所那你可以抛出一个异常。咱这呢,跟那个可重入锁一样。可重入锁里面,如果你在恶意释放锁,它会怎么样呢?啊,咱们看这个think里面,咱之前就看到过啊,啊有这个拆的意思,如果你是恶意释放所的话,可以抛出一个这样的一个异常监听状态异常。
23:02
那我们也可以这样子。咱们也可以去po一个,然后监听状态异常来提他一下啊,This lock is,或者说是does not does not belong to you对吧,To you啊,这个所呢不属于你,我们可以抛出个异常啊,不知道这个英文写的对不对啊,那我们这样写一下。啊,反正呢啊,你能够大概看懂就就可以了啊OK好,那么咱这后呢解锁呀就行了,那零和一还没有用上了呀,对呀,那咱暂时呢是没有用上,那后续呢,我们会讲那个自动续期的时候,咱就用上去了。啊,暂时你先不管啊。它那么解锁加锁都写好了。那么下好之后,我们来测试一下,看看好不好用,因为这个代码呢,我们用也已经用上去了啊。我们通过这个ribu lock可的客户端啊来去获取的一个ready分布式锁对象。
24:07
通过这个分母的对象,我就可以加锁,然后解锁了,你使用起来呢,非常的方便。好,我们来去重新启动咱们这两个服务,来去试一下啊,来重新启动。那么启动呢,应该是问题不大啊。好,已经启动成功了,那咱在浏览器中去访问一下就刷新啊,再去刷一下,刷一下那代码呢,至少没有报错。哎,说明它代码呢,还是问题不大的啊,来按照库存数量,我们给它改成5000件。库存来保存一下啊,保存完之后呢,我们来继续再刷,再刷,有库存的情况下,我刷了三次啊来库存数量呢,减了三件。哎,已经没啥问题了。那么没有问题的情况下呢,我们再去压力测试一下,在高并发情况下。是不是也是完美的呢?
25:01
好,能打开解密的压力测试工具,把这个呢给它清空掉,然后来去运行。好来看啊,那么这个性能呢,可以达到啊,将近600多的性能,对吧?啊还不错啊。啊,600的性能。那五五五千个请求全部发送完了,最终库存有没有减为零,来点击已经减为零了,那说明咱们这个代码呢,可从中锁定代码呢。写的呢,还是能够扛住咱们这个高并发的啊。OK,那么咱就基本上就实现了。
我来说两句