00:00
上节课呢,我们加入了UID来自于防止所得误删。那我们先判断是否自己的锁,如果是自己的锁,那我才能去释放锁啊。那我们这种写法有没有问题了呢?好,我们来去仔细分析一下啊,比如说呢,我有一个请求,然后过一道锁了。执行完业务操作之后啊,开始去释放锁,那么先判断是否自己的锁,那于是呢,我们就判断了一下,我们发现呢,是自己的锁。那么然后呢,开始准备去删除锁了哈,走到这个地方判断完了,哎,发现是自己的锁。可能刚刚判断完,然后三秒钟时间到了。那所呢,自动释放掉了。那于是呢,第二个请求,然后立马获一道锁,开始执行业务操作。哎,那我们第一个进球怎么办呢?在释放锁了呀。那么此时它释放锁,释放的是谁的锁呢?是第二个请求的锁了。哎,第二个请求刚刚获取到,所可能就被第一个请求呢给释放掉了,因为他发现的是自己的所。
01:05
但其实已经过期了啊。但他不知道啊,他依然会去释放这个锁,就会把第二个请求的锁给释放掉。导致第二个请求呢,就无所裸奔了啊,导致并发性的问题。那怎么避免这个问题呢?那一定要分析一下咱这个问题是怎么产生的。产生的原因呢?是因为我们的判断和删除之间没有原子性导致的。那既然没有原子性,就有可能会被别人呢横插一脚。你刚刚判断完,然后锁过期了,那于是其他人会一到锁了啊,你在一删除的时候,删除的是别人的锁了啊。那如果我能够保证他们间的原子性,那么它就可以避免我们这种情况发生啊。那怎么保证它们的原子形呢?那在里面我们一个指令可以保证原子性。比如说之前我们获取所,那么和咱们的过期时间,我们保证了原子性。
02:07
那么咱怎么保证原子性的,就通过一个指令保证的呀,我们通过一个啊set让KV啊ex,然后设置一个过期时间,然后最后来一个NX保证原子性啊。那我们的判断和删除也需要保证原则性。那有没有这样的一个指令可以保证原子性呢?啊,没有这样的一个指令。没有哪个指令既可以做到判断,又可以做到删除的。那我们只能借助于撸啊脚本那么来去实现了。好,那么来看一下啊,也就是说呢,我们这个地方啊,也需要保证原子性,就是我们这个判断判断和释放所,那么之间也要保证原子性,那我们最终呢,决定的使用螺瓦脚本和保证原子性。卢瓦胶本到底是个什么东西呢?那我们可以去认识一下卢瓦胶本哈。
03:04
那我们打开百度,我们来去搜索一下这个撸啊。那乱是什么东西呢?我们有一个菜鸟教程。啊,它有说明哈,所以呢撸R呢,是一种小巧的轻量小巧的脚本语言,它确实非常的轻亮小巧哈,那编译过之后呢,就有100余K。那么并且呢,它这种标准C语言,C语言来编写,并以原代码形式开放,那它跟我们的Java有点类似,我们Java呢是底层啊,也是C或者C加加语言来写的。那么其设计目的呢,是为了嵌入到应用程序中,那么从而呢,为应用程序提供灵活的扩展和定制功能,他这里说的非常好听啊,其实说白了,那么乱呢就可以做呢做外挂。啊,做外挂。那么市面上90%的外挂程序啊,都是脚本来去实现的。那么来看一下啊,它的应用场景呢,有游戏开发,然后呢,什么安全系统啊,还有什么如入侵啊,监测系统啊,那其实说白了呢,它可以做外挂,也可以反外挂。
04:10
啊,那么以及呢,独立的脚本应用啊,脚本应用也可以用它,那这样的话咱就不一一去介绍了啊,总之的话呢,可以嵌入到别的应用程序里面去啊。那么呢,咱们就是C语言了,你写的。那么罗瓦脚本呢,提供了非常易于使用的扩展接口和机制,那么有速读语言来提供这些功能,那么罗R呢,可以使用它们,就像本来就内置的功能一样,我们知道呢,游戏脚本啊,游戏啊,咱一般呢是用C或者C加C加加语言写的啊,我们的呢也是C语言写的。哎,他呢,就可以使用这些内裤。那呢就比较聪明,他主动对我们的瓦脚本来提供了支持。那么撸啊脚本到底该怎么去玩呢?还我们需要先去做一个环境安装。那环境安装呢,我们这里不打算去安装了啊,因为我们这里呢,呃,Release里面主动对它提供支持,我们就直接在一个指令里面来执行R脚本就可以了。
05:10
那么在我们的release里面呢,可以演示一下,有一个指令叫eva指令,那么这个eva指令呢,啊,很多同学呢,可能都没有玩过啊,我们可以连上release去看一下啊,来一个一吧指令它就有提示了。好,这个指令呢,咱可以拷贝出来,然后解释一下啊好让呢,给它放在我们的啊这个里面去,好咱来去开一个啊新的嗯,文本好好这是咱们的撸啊撸啊脚本。Va脚本,那么罗va脚本呢,咱的release呀,对他主动提供了支持,那么指令叫eva指令。那么这个eva指令,那么eva呢,就是指定名称啊,然后script就是我们的脚本了。那么number case就将来呢?我可以向脚本里面来传参数。
06:03
啊,传参数你要传几个K啊,你这个K列表有几个。然后呢,剩下的呀,就是阿格阿格列表了啊。那么咱现在呢,先简单的认识一下,那后续呢,我们会演示这个指令到底该如何去玩。那我们来先解释一下啊,那么R脚本它为什么可以保证咱们的原子性能,保证我们这个操作原子性能,因为撸R脚本啊,它可以一次性发送多个指令,那么给我们的red。好,他呢?可以一次性发送多个指令。那么给。相当于呢,我对多个指令打了一个包装啊,打了一个包,然后一次性发送给release啊RA release我们知道RA release呢,它是单线程的啊,单线程的那么它执行指令,它是遵守啊,遵守咱这个Y,然后是八啊Y,那么这样的一个规则。
07:09
啊,规则来以指定的来来以执行的,啊,正是因为它是单线程的,所以它执行指定的是one by one的。那么只要是我一次性发送给他的指令,这个指令时间,呃,指令中间,指令中间啊,不能被别人横插一脚。那么它就可以保证咱指定的原则性了。哎,隋唐的这个原子性啊。那保证的方式呢,也非常的简单啊,我只要一次性发送过去就可以了。好,那么来看啊,Eva这个指定该怎么去玩,我们先写一个入门程序,那入门程序肯定是永远的hello word呀,来看这个下面就有一个入门程序啊啊,打印一个hello word。用在Java里面呢,比较复杂哈,那在乱脚本里面还是比较简单的,那我们可以去看一下怎么去打印,那我可以来一个啊脚本啊,Script的脚本,第二个参数啊。
08:03
那这脚本呢,来一个print,然后然后呢,在这里面可以打印一个hello word。啊,来个单引号,因为呢,在这里呢,双引号在外面已经使用过了啊,在里面呢,只能使用单引号了。那我直接回车可不可以呢?他就会报错。他报什么错呢?他说呢eva指令,然后呢是执行出错了呀,啊什么错呢,错误数量的,错误数量的参数。啊,那么eva指定呢,一定要注意了啊,那么有两个参数是必须的,一个呢是你的脚本一定要有va脚本。然后呢,还有这个number key啊,你要像脚本里面那传什么参数,传几个key参数。哎,那么K它有什么东西呢?我现在不清楚,那不清楚的情况下,你可以传一看,他传一个有零,我先不传。好,那我一回车呢,现在就可以执行成功了啊,那么执行成功之后呢,来看他没有报错,但打印结果呢,不是我们想要看到的,Hello word。
09:05
而是一个NRL,那为什么呢?因为啊,在我们的rar脚本执行过程中啊,它控制台输出的不是咱脚本的打印,而是脚本的反义值。那么它输出的啊,不是print的内容啊,那么而是返回词,而是返回词,而是的这样的一个的词啊。好,那我们可以去啊,演示一下啊,那么回到咱们这个控制台,那么可以呢,再来一个一吧,如果你想打印hello word在这里啊,在原生的罗脚本里面,它是可以打印出来的,但在red这个罗脚本里面呢,它打印的是一个输出的是打配值。你来个可以打印出来了,那么hello word呢就搞定了啊。
10:00
好,这一点呢,一定得要注意它,这是一个细节性的问题哈。好,那么这个撸啊脚本呢,咱已经入门了呀,啊会hello word不就入门了吗。但是呢,咱不能满足于此,你光会这个还写不出分布式所啊,还写不出分布式所所需要的啊,瓦脚本。那我们来看那基本语法,咱要不要看到呢?那这呢你可以不看啊,它里面呢,有输出这个hello word的,那么也有什么呢,也有什么注释,该怎么去写的,还有一些什么标识符,关键字这些东西。那关联字这些东西啊,跟Java里面的关键字呢啊很像,它很类似。那什么全局变量这些东西啊,那我们直接去看它的数据类型。那数据类型啊,其实你也可以不用去管它,因为R加本里面它是弱类型的啊,我定义变量的时候,不像Java里面,你定义变量要去生明类型。那在魔法脚本里面呢,但是可以不用去生命类型的,但你看别人怎么玩的啊。那么变量呢?就分成两种变量,一个是全局变量,一个是局部变量。
11:04
好,那么咱这里呢,这个变量啊,我们还是得要了解一下的啊,那么它的这里呢,有嗯变量有两种,一个呢是全局变量,那么还有一个呢,是局部变量。啊局部,然后变量,那么全局变量怎么回事呢?比如说我来一个变量A,那等于五,这就是一个全局变量了,那如果你要说明一个局变量,你表达一个log等A等于五啊,这就是局部变量了。那全局变量和旧变量咱可以去演示一下啊,那比如说呢,我可以在这个1VA指令里面,我来去声明一个变量,我来一个A等于五,那么此时呢,它就是一个全集变量了。你来一个啊A来打印出来好,那么最后呢,来一个零好,我一会说怎么样呢?哎,报错了啊,为什么报错,是我写错了吗。啊,那不是我们写错了啊,来看一下他说脚本尝试去创建一个全局变量A。
12:07
那么在re里面啊,它不允许我们去声明,声明全局的R脚本变量啊,不允许我们在罗化脚本里面声明全局变量。OK,它只允许声明本地变量。好,这个呢,咱就要去使用第二种写法了。好,咱可以来个一吧。然后这个里面啊,咱们要加一个logo,那它就变成一个局变量了,那我们一会说它可以打印出五的值了。好来看啊,那么变量,因为它声明方式呢,非常简单粗暴啊。可以这样子。啊,那么全局变量啊,它就可以在很多地方都可以去使用它,那球变量呢,只能在一个代码块内部来去使用,那么咱应该都能理解哈。好,那我们来去看啊,变量咱已经会了啊,那么循环咱可以简单的认识一下,哎,循环怎么玩等等,咱们最最熟的啊,应该就是for循环了。
13:04
啊,Java里面咱经常去玩一些造型啊。那么它for型还怎么样的一个玩法呢?来看啊,那它的写法呢,是这样子的,来一个for,那这是一个变量。那这是一个变量,那么然后呢,XP1XP2XP3,然后来一个度,中间的是执行体啊,是我们这个循环的执行体,那最后呢,循环结束来一个N。那么来看啊,呃,咱们这个在罗瓦脚本里面啊,它不像我们的Java有划括号来,可以代表一个代码快结束了,对吧?啊那么啊,比如说呢,我一个放循环结束了,来一个画括号终止就可以了。那么一个if片段结束了,它也是有个画括号,可以表示结束了啊,然后呢,就是画括号,开始画括号和结束画括号啊。那么在lua脚本里面,它没有这种画括号,那么也不像Python里面,Python的话,它有严格的对齐方式啊,哎,缩定方式。
14:01
来那么不同的缩进。它的这个等级啊,代码片段等级就不一样。好,那么在脚本里面,它既没有严格的缩进,也不像我们Java里面有画括号为代表啊代码块。那这时候呢,使用这个end,通过for可以开启一个代码块,那通过if也可以开几个代码块,那么结束的时候呢,一定要加一个N。哎,不然的话呢,他就不知道哪里结束了啊。到哪个位置结束。啊,这一定要注意。啊来看啊,那么这个呢,什么意思呢,就是变量Y,它会从XP1变化到XP2,然后呢,每次变化以XP3作为步步长来递增,我们这个R变量。而比如说呢,我想输出一个一到十之间的数据,那这个地方可以写一个一,这个地方可以写一个呢,写一个十,这个地方也可以写个一。那就什么意思了呢?就从一变化到十,每次变化以一作为步长为递增。
15:05
那就可以输出来输出一到十之间的数据了,啊,还这样子。那么这个便利呢,我们也不打算演示了,因为在咱的分布式所里面,我们也用不到,那你有兴趣呢,可以自己去演示一下啊,你下面呢,就演示代码在这个位置。好,那我们呢,回过头来来去看一下咱们这个流程控制,哎,我们要用到的就是流程控制了。那么流程控制什么东西呢?啊,就是咱Java里面的那么if。然这是if加if,还有这个if。啊,那么这几个关键字。那么这个if我们来看啊,啊,首先呢,这个if里面呢,你可以放一个条件,只要在如果这条件成立的情况下,它就会执行这行代码。啊,那么啊,然后呢,是你还可以有啥的,有这个is还是if啊注意这中间没有空格啊I if写在一起的,那你也可以再写一个条件后面那你来一个,在如果成立的情况下,它会指走我们这个代码块。
16:07
那最后呢,你可以来一个I,如果以上条件都不成立,开始执行这个I,下面的最后呢,来一个end就可以了啊,代表就结束了。好,咱们去看一下它的,嗯,这个啊,分支控制啊,它的一个玩法。那么分支控制的玩法呀,它是有,嗯,就是分支,然后控制。控制它的玩法呢,是通过这个if if那后面呢,你可以写一个条件,那不用这个小括号啊,它不用写小括号,你直接写个条件就可以了。反正是一个布尔的表达式,如果他成立了,你可以来个than,那么它就会走这个than下面的这个代码块啊。这个可以写一个代码块,那么然后呢,我们还可以写,还能写use if,那么if后面也可以写一个考点,那么条件成立的情况下,它就会走到这个Z里面去啊。
17:05
做这个Z里面去,好,咱把这个呢,再给它拉大一点。好,那么还有呢,是咱们这个成立的情况下,它会走这个代码块啊代码块,那么最后啊,我们还可以有一个I,如果上面条件都不成立,那我可以走I里面这个代码块啊,那最后呢,咱整个分支控制结束了,你可以来一个N的好这样子,那么指令介绍完之后呢,我们可以演示一下,那么这个分支控制该怎么去玩。那我们可以呢,写一个一吧指令,然后呢,这里面啊,咱可以来一个判断,比如说if,那么十大于二是吗?啊如果大于20,我们应该怎么样来一个Z不就一个那么十。那再来一个I,我就可以去re腾一个20,那最后呢,我的整个代码块结束,又来一个end,那就可以了。
18:03
那我写完之后呢,来一个零回回车,请于输出多少呢?输出我们的20。这个呢,咱在Java里面以前有写过。那么A啊等于多少,B等于多少,然后A大于B吗?A大于B咱就输出A对不对啊,如果不大于B,咱就输出B嘛,那这样子。啊,这非常容易啊。那我们这个代码虽然出来了,但是我们这个写法呢,明显不符合我们平时的一种习惯。因为这两个呢,我们要比较的参数呀,往往呢,哎,可能它不一定是十和20,也可能是三十四十呢,也可能是五十六十呢,咱应该动态的往R脚本里面可以传两个参数来应用比较。按控制逻辑来给我比较。好,那么怎么动态的向面传,向里面传参数呢?好,那么咱们可以去看一下了啊,来一个啊一吧,我依然使用上面这个螺脚本,我们在这个基础上来改一下。
19:00
那么传递参数呀,我们可以通过K列表和R的列表来遗传。那比如说呢,我要传一个那么十传一个20这两个参数。那么这十和20咱以空格来定分格。那么这个十和20到底是K的列表呢,还是二的列表呢?那看K列表和R的列表它之间啊,是用空格来去分割的啊,空格分隔的,那么KK呢,它可以写多个,那么阿格呢,也可以写多个,那么K它用什么来一分隔呢?K与K之间用什么分隔呢?也是空格了,一分格的。虽然它都是空格,那么都是空格的情况下,那我哪些是K,哪些是呃二呢,那就搞不清楚了。那咋办?我们就可以使用啥呢?使用这个number key,哎,咱们有一个参数叫啥呢?叫key这样一个参数就是你K的数量。那比如说呢,在这个位置,哎,我就可以写了,写上一个,比如就写一个,呃,二代表什么意思呢?代表我这后面的参数,前两个是T列表。
20:08
那后面两个呢,剩下这两个呀,就是阿列表了,就是阿格参数列表。好,那我这里呢,呃,简单的理解一下啊,那么在代码在这个如R脚本里面,我该如何去拿到这些参数呢?拿到K列表里面的参数啊,R列表列表里面的参数呢,那才可以这样的啊,那我们呢,可以通过这是一个固定写法,通过这个K,然后呢,通过参数下表是从一开始的啊。比如说我T1,那么大于,那么还有这个阿格列表呢?阿格列表怎么写呢?那咱有这个阿格位是一个固定写法,还大于阿为一吗?那如果大于阿为一,比如说呢,我就输出来了,输出这个啊,输出这个来一个K,然后是二,那么这样子。那么如果你不大于的话,我就输出含量,输出这个啊阿格比,阿格比是。
21:07
二这样子,那最终输出输出是多少呢?我们可以去设想一下。那么这叫K1,那无非呢就是这个十了,那么阿为一呢,无非就是这个30。那么十大于30吗?如果大于30,我要输出是K2,有20吗?哎,否则我就输出是40压力,那现在应该输出多少呢?应该输出的是20。啊,那么应该输出啊,输出是40对吧?啊,输出是40。因为咱明显十呢是不大于不大于30的啊,是小于30的,那小于30咱应该输出的是阿格V2,阿格V2也是40嘛,咱应该最终输出的是40,好,我们来去看一下,那答应结果呢是40。好,我们就可以动态的往里面可以传参数了。啊,那我们呢,再去强化一下啊,在eva里面,在eva这个鲁va脚本里面呢,我们也可以去返回多个值的啊,咱可以去一个画括号,我来一个十,然后是20,然后30,然后那是40,好,我可以传,我可以返回多个参数。
22:17
那么来一个零,我这时候不需要动态往里面去传传参数啊,我打印呢,结果呢是十二十三十四时。那说明脚本确实可以一次性返回多个值。好,那我这里呢,给他改造一下,比如说呢,我向里面去传了很多个参数。啊什么三,比如有十,然后有20有30,有四十五十六十啊七十八十这样子啊,还有90对吧,我算了很多个参数。那么哪几个是K?哪几个是阿格韦呢?那比如说呢,我想去输出一下这个K啊一的这个值,我还想去输出一下这个K,然是二的值,然我还想去输出一下这个阿格V,然后是一的值啊,阿格比一的,以及这个是阿V。
23:10
然后是二的这个值。好,那我们这里呢,比如说我是有四个是T列表。那么说明说明前四个就是K的列表了哈,就这个意思,前四个是K的列表。那么剩下的就是阿格B列表了。那我传了很多个参数,但是在这个里面呢,我可以只用其中的一部分参数。那我可以我可以,我可以呢,只用一部分,没有必要全部都用,用一部分呢,也是没啥问题的啊。那最终打印结果是多少呢?好来看一下啊,那么咱K列表输出输出的是前两个应该输出的是十二十,对啊啊,那么我们这是K列表吧,前两个不就十和20了吗。那么剩下这几个是啥呢?是我们的八个列表。
24:00
那么阿格列表呢,咱打印的是也是前两个,那所以呢,打印的是五十六十,所以该打印结果呢,应该是十二十,五十六十这四个参数,好我们一回车给打印出来了。那就这四个。那么经过咱们这样的一个呃案例啊啊代码案例,那么你们对咱们这里面的参数呀,应该比较了解了哈,那么1万呢,它就是一个指令,它可以执行我们的R脚本。那我们这里呢,还有这个script啊,他说的是lua脚本,那么字符串。啊,脚本字符块,那么还有呢,是咱们这个number啊,Case number kiss。它是我们K列表的元素,元素数量,你有多少,你有多少个元素,多少个K元素。好,那么将下来呢,我们可以通过K,然后来去获取这些元素啊好,那么然后呢,就是我们这个啊KK列表啊K列表,那么以空格来去分隔,那么然是这个呃,是我们这个R个列表列表,然后它也是以空格来去分割,那么K和阿格这个列表元素。
25:22
咱怎么去获取呢?好,那么如果是K列表的话,我们要通过K要加一个下标来去获取,那么这个下标啊,咱是从一开始的啊,从一开始,那我们的阿格列表,咱们的获取方式呢,通过阿格里能来获取的,那依然呢要加一个下标,那下边的话依然是从一开始。
我来说两句