00:00
前面呢,我们说了一下这个look方法,而且呢look方法的两大特点,那第一个特点我们之前体会到,它呢,会有一个看门狗机制,在我们业务运行期间帮我门锁进行自动续期,还有第二个为了防止死锁,我们这个加德锁默认也是30秒的过期时间,即使由于我们业务宕机,我们没有手动调用解锁代码,那30秒后呢,Red也会对它进行自动解锁,当然我们加锁的时候呢,还可以用它高级的办法,比如我们look.look来指定十,那意思呢,我们这个锁十秒钟以后我们自动解锁,相当于我们给锁指定了一个过期时间是十秒,然后我们来执行业务,即使我们业务不解锁,那十秒以后呢也自动解锁,然我们业务执行的快,那就应该执行完成以后进行解锁,好我们来测试一下这个方法,我们现在来测,我们把这个look去掉,这个look呢是一个阻塞式等待,然后呢三获取。
01:00
到锁以后呢,就会执行,我们现在来使用另外一个还是这个look方法,我们可以指定时间我们来写一个十,然后呢写一个time unit seconds,相当于是呢,我们如果自己获取到锁,那十秒以后就自动解锁,那它的这个代码就是十秒钟自动解锁,自动解锁,但是呢,我们现在要测试一个问题,什么问题呢?假设我们业务是30秒,而我们锁只有十秒,这个十秒呢,指的是我们占锁的时候,在red里边这个K的过期时间我们是十秒,那假设我们业务执行到11秒左右的时候,我们这个锁已经过期了,如果把它删掉,那就有新的人就又能占用锁了,所以相当于我们同一时刻不能将两个人或多个人我们同时锁住,只允许一个进来执行,我们来看,我们一旦指定了这个十秒锁,会不会有这个问题。
02:00
那我们想如果出于设计,我们既然有开门狗就应该是这样,我们即使指定十秒,我们业务呢,执行快要过期的时候,开门狗再给我们来一个自动续期,我们继续来往上加,我们看会不会有这么样的一个效果,好,我们来测试一下,我们来运行起来走。那么还是把我们这个服务呢,我们来重新运行起来,我们使用这个加速方法,我们也不用跑多个,我们就来运行这一个,我们来测试一下我们的这个效果,我来发送hello请求,来稍等,我来等待清空我们这个控制台。我们来清空这个控制台,好,我们来现在来访问,Hello,走推车,那我们现在获取锁只有他一个人肯定能获取到,我们来看这个锁时间呢,剩六秒走四,我们看能不能自动续期。诶,我们发现呢,我们用了一会儿以后,这个锁自己没了,然后呢,我们来刷新一下,那我们发现它没有自动续期,那没有自动续期那完了,那相当于如果我们再发线程进来,就又能抢到锁了,所以我们这一块呢,就会有一个问题,包括我们来看他现在虽然在这执行,但是我们如果再来发请求,我们肯定还能抢占到锁,我们在这儿打印呢,会有加锁成功,因为它没有自动续期,我们再来看一下,好它的这个过期时间的一秒,好时间过了,如果我再发一个请求,即使我们这个没有执行完,我们在这儿还转圈,但是我们来回车在这儿呢,又会有加锁成功,所以我们发现啊。
03:30
它同时不能锁住我们所有的东西,那这就是由于我们给锁设定了一个自动超时时间,而且一旦出现这个问题以后,我们来看结果返回,结果返回这一块也会抛异常说我们尝试解锁。说不能用我们这个当前线程解锁,也就是说它也判断出来了,我们这个锁呀,超时是reddi自动删的,相当于我们现在两个线程,我们给锁设置了十秒的时间,我们线程执行要30秒,十秒以后过期了,那下一个人相当于进来以后就占了,但是呢,20秒以后我这个人要删锁,删的其实是下一个人占的锁,他这也判断出来不是我们当前的锁,所以我们说如果一旦我们来用这个方法,一定要小心,就是我们在这儿指定的这个时间,那自动解锁时间,自动解锁时间一定要大于。
04:27
业务的执行时间,这样呢,我们业务执行完,我们手动解锁,哪怕我们业务崩了,我们也会在指定的时间解锁,但是我们出现的唯一一个问题就是我们这个问题就是如果我们使用了这个方法,指定了过期时间,在锁超时的时候,锁时间到了以后。我们不会。自动续期不会像我们这个lock方法一样有自动续期,那为什么会出现这个现象,我们来给大家看一下它里边的一个源码,来controlrl out,我们来点进它的时现,来看一下red look,好,那们现在来看我们来加锁,加锁呢我们在这我们自己指定了一个时间,然后呢会调用下面的look方法,那这个时间呢,我们指定了时,那我们继续来往下调,好我们来调这个方法,调这个方法呢,他拿到当前的这个线程ID,然后呢,他在这TRY块,那就是尝试来获取,如果返回一个now,说明他认为所获取到了方法结束了往下运行,否则呢,我们这个VR处也还是调用这个方法一直获取,只要是呢,那就说明获取成功了,那么就来看这个方法TRY2块,来点进来,这个方法呢,相当于是来获取锁,获取锁呢会调用get。
05:49
Get里边呢,又掉了一个这个方法叫try acqui anthnic,好,我们来调用这个方法点进来,那么传的这个时间就是我们自己指定的十秒的时间,好接下来大家看这呢,有两个判断,如果我们来传了十秒,它是判断IF10不等于负一,那相当于我们传了,那就在这,如果我们不传,我们来看一下,那如果是调用的这个方法,我们不传,我调用这个look方法来点进来,还是这个reddi look,那我们会看,它会自己传一个负一,那就是我们传了用我们的,我们不传用负一,那相当于我们继续来进来,Crl al来点进来,走,我们现在传了,用我们的,我们来继续点进来,CRL按住,我们来是调用这个方法的点进来,好,我们还是调用这个点进来,那现在呢,自己传了十,十不等于负一,那我们确定就是走这儿,相当于我们自己传了,那就走这,如果我们没传,时间是默认的。
06:50
那我们就走下边,那么来看这两处呢,有什么区别,如果我们传了过期时间,它就执行这个方法,叫try look inner anthnic,叫尝试加锁,我们内部的使用异步方式进行加锁,按照方法名翻译过来就是这样,而且这个时间呢,这是我们制定的,我们来点进来看,诶我发现呢,他先把这个时间转换成一个叫internal look list time,相当于我们内部锁的释放时间,他把这个转换过来,转换过来以后呢,他使用command,我们这个命令的执行的,相当于线程池,我们看到这一块呢,也是一个Lu瓦脚本,他把这个脚本呢,相当于发给red去执行,那就完了。所以呢,一句话,如果说我们自己在这儿传了时间,那他就直接执行我们这个脚本去rabbits里边站位,并且呢,超时用我们船的这个时间,好,那我们来说我们的这两个原理,第一个如果我们。
07:50
我们传递了锁的锁的超时时间,时间。就执行脚本,相当于发送给red,发送给发送给red执行脚本,然后呢进行战术。
08:11
而且默认超时就是我们指定的时间,相当于我们现在指定的时秒,但是现在如果是我们没指定,第二个如果我们没有传递所得超时时间,我们相当调了这个方法,如果我们未指定未指定所得超时时间,那么来看它是怎么做的,还是来到这儿,那未指定相当于就来到下边的方法,下面的方法呢,还是一样,它还是调用try look in the ethnic,跟这个一样,但是呢,这要整一个时间传了就用我们的,没传我们来看用什么,他会呢,拿这个获取。一个接在连接这个管理器里边,然后呢,得到配置,得到配置以后呢,这有一个叫get look watchdog out,相当于获取锁的开门狗的时间,好,我们来把这个时间点进来,我们把这个点进来,来看一下,诶,这是30乘1000,时间呢是毫秒,所以说我们就看到了这一块,如果我们未指定时间就使用,就使用我们这个,这个呢,就是我们说的这个look watch dog come out,就是我们看门狗的超时时间。
09:23
来在这儿备注一下,就使用它,这就是我们这个看门狗,看门狗默认时间。那这个时间呢,默认就是30秒,所以我们也解释了,我们之前默认加速,它给了一个30秒时间,但我们来继续看,那我们没有指定时间的时候,我们来点进来好,还是这个方法,还是传耳块,我们来点进来,我没有指定时间走下边所呢默认超时用开门狗时间,然后完了以后他还是调用这个方法,相当于给redis发送命令,指定好时间,指定好线程,好,那发送命令,那命令只要一发送出去,他在下边来看啊,它会返回一个,这个叫future,这个东西如果大家学过guc里边的异步编排,那这个呢就很好理解,没学过,我们后来再说,大家主要来看一个说明,我们这一块的代码是去red进行战锁,如果站成功了,他会在这来监听oncom,那就是站成功了,站成功了以后呢,这有两个参数,一个是异,一个是它E代表异常一不等于空,那就说明有异常,有异常就直接返回了,那没异常它还会调用。
10:33
那么这个方法我们来看这个方法,这个方法呢,它叫schedule exp,什么renew之类的,把我们这个线程号传进来,那么就来看一下这个方法,什么schedule schedule就叫调度的意思,我们来点进来看一下,点进来呢,它就是传入这个线程号,然后还是在这put ifent,相当于给里面放东西之类的,别的不看,主要看这下面呢,这有一个叫renew expression,相当于叫重新设置过期时间,好,我们来点进来看这个方法,这个方法呢,在下边们来看这个or。
11:10
大家就来看关键字就行了,不用理解每一行代码,我们获取一个连接管理器,整了一个new timeout,然后呢,New了一个,注意这个叫timer task。叫定时任务,这个定时任务什么时候执行,我们来看啊,这个定时任务要执行就运行这个run方法里边的整个内容,整个内容呢,主要是来运行这段代码,什么renew expression。好,我们来点进来,这种代码呢,还是一段落R脚本,这个脚本呢,相当于调用red的call,相当于red去来调用我们这个设置超时的方法,K是什么,值是什么,包括超时时间有多长,我们来看到,诶这个时间呢,是internal look list time这个时间我们再点过来,来看这个时间呢,我们看在这儿构造的时候,这儿还有一个构造器,这个时间在这儿相当于red look1创建的时候,这个时间诶又是我们这个看门狗时间。
12:05
好,刚才说了这一大堆一句话,就是呢,如果我们未指定超时时间,然后呢。只要战锁成功,只要战锁成功,那么这个叫战锁成功,然后呢,就会启动一个定时任务,定时任务的作用就是呢,重新。重新给所设置过期时间,但这个重新设置设置多久呢?也就说给他新的过期时间,新的过期时间就是开门狗的默认时间,开门狗的这个默认时间,好我们刚才看到了这段代码,但是我们这个定时任务是多长时间执行一次,因为我们业务超长,我们要去续期多长时间执行一次呢?我们可以来看一下这个续期操作多长时间执行一次,还是这个方法look方法好,我们来点进来,CTRL按住TRY块好点进来,我们每指定时间走下边,然后呢,在这来进行任务调度点进来,点进来呢,重新设置过期时间点进来,然后呢,这是我们这一个timeout,相当于我们的定时任务,我们来看这个task,这个task什么时候执行,大家看test在构造的时候有一个叫delay,延迟多久以后执行呢?我们来看,这就是看门狗时间。
13:29
除以三相当于十秒以后我给你续一个期,而且续期成功以后呢,它相当于又是重复把自己调了一遍,看我re scheduledu的itself自己呢重掉一遍,那相当于续期成功以后,十秒以后呢,再续一个期,十秒以后再续一个期,那我们发现这一块呢,续期就是这么来续的,1/3的开门狗时间以后进行续期,相当于我们这个只要占锁成功,他不会立马续期1/3的开门狗时间,好,那么这个时间呢,来在这备注一下,这是看门狗时间,然后我们1/3相当于十秒以后我们给它续一个七,所以呢,我们来看我们这段业务代码,我们之前用这个加锁的时候,我们就会十秒语续期,大概是这个样子的,我把这一块注掉,我们来启动一下我们这个,我们把这一块注掉,还是返回我们之前的代码来看是不是十秒与讯息,好,我们现在还是在这来准备来发送这个请求。我把。
14:30
这个red呢,我来确认一下,我来刷新一下,来看这个零里边,好,现在没有锁,没有my lock这个锁。我们来把这一块代码我们来都来清空,把这个控制台呢,我们来清空,来稍等一下,我们来清空我们这个控制台,好,我们现在来,我们来尝试执行hello方法,那现在是原生的执行好回车hello方法,我们来到这个red里边,我们来刷新一下,看一下这个mylo,好,这是26,如果是十秒续期,大概是在好来看一下啊19好,我们到19秒的时候,稍微有个延迟,我们续到了新的30,那么再来执行,在十秒以后呢,又会再来续好。
15:10
走哎,又续到30,只要我们业务在执行,那么就一直在这儿续期,相当于会有一个定时任务,每隔十秒,每隔十秒,每隔一个1/3开门狗时间,每隔十秒都会自动再次,再次续期,续到多久呢?就续到我们的这个满时间续期,然后呢,续成续成什么,续成我们这个满时间续成我们这个30秒,所以这就解释了我们为什么我们自己调用这个look给的这个方法,它没有看门狗,而这个有看门狗源代码呢,就是这么来写的,而且看门狗机制就是这么来运行的,所以呢,给我们一个最佳实战,我们以后怎么用最佳实战。
16:02
虽然说我们可以用这个lo加锁,而且也有看门狗的续期,但是呢,我们一般还是推荐大家来怎么用使用我们这个look方法,好这个lock方法,这个方法的作用呢,就是我们明显的指定一个所得超时时间,而且呢,我们还省掉了我们这个续期的过程,省掉了咱们整个续期操作,那有些同学说那业务超时了怎么办?所以我们这一块呢,就给他时间给大就行了,比如默认30秒,那就30秒呗,我们这个业务如果都能超30秒,那说明业务都完蛋了,肯定都有数据库各种连接不上了,所以呢,我们还是在这儿来明显的来指定我们这个业务时间,而且呢,业务只要执行成功以后,我们就手动解锁,相当于使用指定时间加锁,然后呢继续来手动解锁,就算不解锁,最慢也就是30秒以后解锁了。但是它里边的整个开门狗机制,如果我们用了look方法,开门狗机制大家也知道一下。
我来说两句