00:00
我们继续来完善我们商品信息的这个上架功能,首先我们这个秒杀商品的这个信息,我们基本信息呢,已经上架过来了,接下来我们要获取到SQ的基本数据,那SQ的基本数据需要调用远程服务来进行一个查询,那么来到这个远程的商品服务,商品服务我们来找他一个controller,这个我们来主要查SQ,那就是SQ info controltrler,那么现在呢,就来查SQ的详情,那就直接拿到这个请求来执行就行了,CTRLC,那么接下来在这来写一个远程接口,好,这个远程接口呢,就是来product,我们的份service,我们远程来获取商品服务的相关功能接口来。然后呢,我们来写一个注解叫分client,那现在呢,要获取的功能,我们先把这个功能复制到这,好把这个public呢,我们就来去掉,然后我们来把这一块来删掉,还有我们的整个路径来也完善一下路径的这一块拿过来,那按照SQ信息来获取到它的这个详情,那接下来那就是我们想要调用的服务,那就是远程的商品服务,那么这个远程调用就准备好了,来到我们的这个秒杀服务里边,好,我们同时把这个远程调用也注入过来,商品服务product的这个远程调用商品。
01:22
服务的这个远程调用们来到这商品服务at一个owa这个远程调用呢,我们来放到下边,那现在要获取SQ的基本数据,它呢有一个方法叫英仿,这个呢别叫英仿,这个英以后可能有好多英要重名,那我们就叫SQ英。Get squ英符,我们按照这个方法名,那现在呢,我们就来获取squ的信息,只要请求路径对,传的参数对,那就没问题,我们现在来点一个get SQ英法,那想要查的SQ信息那就在这里边,这里边呢点一个我们这有一个get SQ ID,我按照它来获取,最终呢得到一个R对象,同样的我们把R对象呢,整个数据拿过来,那远程的商品服务,那直接来到这个SQ的CTRL了,那么返回到这个R对象里边放的这个属性呢,叫SQ英fo,那这个就比较奇怪了,然后我们接下来拿过来,那么就从这个sqfo里边,我们当然得判断,如果说这个R对象squ info点一个get code,我们是零的,那就是一切是成功的,那成功的我们才能给它获取数据,Sqfo点一个们调用get data get data呢,我们指定的K,那是这个,然后呢,我们要把它封装成。
02:41
什么样的数据,我们专门呢远程服务返回的SQ信息,我们这有一个VO,我就来封装成这个类型的VO,你有一个type reference,那就是这个类型的view,把这个类型的倒过来,那加上封装成一个这个类型的数据,好我们来返回,那现在我们这个SQ的这个英O信息我们就准备好了,那准备好了以后给ready two里边来set上,这有一个SQ的info信息,那这就是SQ的详情信息,来放好以后,在这呢,让它进行一个属性对拷,这个属性对拷呢是考基本信息,那么SQ信息我们查过来就直接给这一放就行了,然后接下来第三步我们就给red里面保存,但保存呢,我们说除了有这个基本数据秒杀信息,我们还要让它额外保存一个我们这个东西叫我们的随机码,这个随机码还有我们的这个结束时间,因为这个结束时间呢,是根据活动来的。从每。
03:41
一个想要在这保存的,我们来看一下,那现在有这个活动信息,那没有这个结束时间,有SQ信息,那没有结束时间和开始时间,那我们就比较难办了,所以我们在这来准备一个start time,这是一个开始时间,当然这个时间呢,我们最好来备成一个日期类,好start time,还有我们的一个结束时间,那我们之前说时间为了好比较,我们之前都保存了K了,那这个K呢,我们设计的是浪类型,我们这一块呢,也可以用浪类型,这样呢比较起来就更快了,好,那就直接来也用浪类型,这是开始时间。还有一个呢,结束时间,那就是相当于当前商品,当前商品秒杀的开始时间秒杀。
04:26
秒杀的咱们这个开始时间,还有我们的这个结束时间,我们把这个复制过来,好放到这儿,这是我们的结束时间,那么现在把这两个准备好了以后,那接下来我们就来放一下我们的这个时间,那这个to里边,那么在这来保存数据之前,我们再来设置上我们这个当前商品的秒杀时间信息,这个信息呢,最终是要来做判断的,来点一个set,一个start time,我们的这个开始时间,那就是当前活动,因为我们这个商品属于当前活动,拿到当前活动的开始时间,把它呢获取成一个。
05:06
我么long类型的这个类,好,接下来我们再来ready,一个to,点一个set,一个end time,这end time我们还是拿到这个结束时间,点一个get,有一个当前活动的结束时间,那这个结束时间呢,我们还是一样把它获取成一个浪类型的值,好那现在呢,我们得到了这两个时间,时间信息我们也设置好了,然后呢,我们再来设置一个我们称为这个加商品的随机码,那为什么要引入这个随机嘛,那么现在来考虑一个事情,就是如果我们这个秒杀接口我们暴露成这样,比如我们叫second q问号,然后呢,你想要秒杀哪个商品,SQID等于一,那你直接给我传一个,这个时间一到呢,我就给你扣库存秒杀,但这个呢,很容易引起我们这个攻击,比如我们来专门来写一个工具,我们就无限重试来发这个请求,那只要你秒杀一开放,那立马这个请求发出去,我们肯定第一个抢到,所以呢,我们引入随机码的目的。
06:07
就是你想要来秒杀,你不知道我的这个随机码,你商品ID知道,那我们肯定是这个商品要秒杀,但是你不知道我们的这个随机码,你发请求也没什么用,所以我们这个随机码呢,只有我们秒杀开始的那一刻们才给你暴露出来,所以们这个随机码我们现在呢,就可以来设置上,那为每一个商品来设置上它的这个秒杀随机码,那red to,那就是我们当前保存的这个商品信息,那在给商品信息里边呢,来重新封装一个就是当前SQ的秒杀随机码,我们private string类型的,我们这个random code,好,我们现在呢,就叫随机码,我们这个是商品的秒杀随机码,你不带队这个随机码是不能秒杀的商品秒杀随机码,那这个随机码的内容,那我们现在呢,就直接给它生成一个UUID就行了,Set一个,我们有一个random code,好,来写一个UUID,点一个random u u ID,点一个to string,好,我们。
07:07
把中间的短横线我们直接替换过来,这是我们秒杀用的随机码,把这个随机码呢,我们重新来拿,提出来放外边,一会儿呢,还要用到这是我们的这个token信息,我们的随机码,然后呢,这个随机码我们放到这儿,你想要秒杀我们这个商品,你不带我们这个随机嘛,我们是不行的。那这样即使你知道了我们这个商品ID,我们要秒杀,包括我们的开发人员也知道秒杀是发这个请求,他呢如果想要内部来抢,然后他带上我们这个商品ID,但是他没有这个,我们自动生成的这个随机码,他也秒杀不了,所以呢,这是一个公平的秒杀,好我们这个随机码呢,我们就来准备好,准备好以后呢,我们这几个数据就放好了,SKU的信息,活动的信息,我们这个SKU里边呢,保存了这些商品的基本信息,以及随机码这些值,然后记住现在呢,还有一个关键信息,叫设置一个商品的分布式信号量,这个呢,其实就是我们当前秒杀商品的库存信息,我们这个库存秒杀不应该是实时去数据库来扣库存,那要去数据库来扣库存几百万的请求进来,我们都去扣,看谁扣成功了是不可能的事情,所以秒杀现在要做的最大的问题,应对这些高并发流量的系统进来。那肯定就是有一。
08:30
的流量是不需要做事的,比如这个秒杀不成功,比如我们现在呢,就100个商品,肯定呢你100万请求,哪怕放进来,最终只有100个人,他才能成功的去数据库来执行我们数据库的减库存方法,所以呢,我们可以来提前在rabbit里边来设置一个这个信号量,这个信号量大家就认为是一个自增量,比如我们这儿有一个count技术,它是一个100,这个信号量呢,我们以前做分布式锁的时候,给大家也演示过red的分布式信号量,然后呢,只要我们进来一个,我们就给它100减上一个,我们减一个99,所以最终我们如果每一个商品都有了这个信号量信息,那你想要秒杀这个相品,我先去red里边获取一个信号量,也就是给你这个100库存减一个变成99,如果能减了,我把你放行,你再做后边的来处理数据库,如果不能减了,你都不用去进行数据库交互,那不用进行后续的操作,我就会阻塞。
09:30
呃,很短的时间,那么就整个请求就会得到很快的释放。我们只有每一个请求都很快的释放,能很快的做完了,我们才可以拥有处理大并发的这个能力,我们大量请求全部进来,我们才能有能力去来处理它,每一个请求都要在这儿阻塞很长时间了,虽然他在数据库秒杀不了商品,是他还尝试在那捡一下,捡一下也没用,但是他阻塞了,然后呢,我们就不可能拥有我们整个大并发流量,所以呢,我们现在要设置一个我们的这个分布式信号量,而且这个信号量呢,设置大家注意,由于我们每一个请求要进来,我们要去减我们的red的计数这个信号量的值,那就是我们当前商品的库存信息,我们现在要秒杀100个,那就是100,那我们要讲,如果我们是带了商品的ID,如我带了ID,我去在这儿,就算以前是伪造的请求,我不带这个K,我没有判断这个K,然后呢,我们现在带了一个SQID,我们去来尝试秒杀,然后一进来由于我们是拿SQID进。
10:35
你匹配的一个数量,所以呢,他直接去red里边查到了,然后给我们减信号量,这个呢就不合适,所以我们来准备一个随机嘛,只有到了我们这个秒杀时间了,然后你知道了这个随机码,你带上随机码,我是按照这个随机码给你来减信号量的,要不然我们每次都这样来减信号量,不带随机码的话,这样就会出现问题,那我们秒杀还没开始,我们可能一些恶意请求就把我们这个信号量就减去了,说明这个随机码呢,又是一种保护机制,减库存的人,你要买我这个商品,你知道随机码了,才能减掉我的这个库存,所以呢,这个随机码在这儿也设置好了,那设置好以后,接下来大家注意每一个商品都要设置它的分布式信号量,所以我们来引入一下red,我们就在每一个里边来设置它的分布式信号量,这个分布式信号量我们来点进来,那在这儿先来引入我们的reddi操作,因为我们整个分布式所之类的,我们全部是用reddi。
11:35
好,那现在来引入一个reddi reddi呢我们就3120版本,那就跟我们以前商品服务里边来看一下,我们引的这个reddi版本呢,无所谓,能操作我们这个reddi就行了,们来找一下我们这个REDDI3120,好,然后呢,把我们这个reddi呢配置我们也直接复制过来,主要配置一下主机地址就行了,好,我们把这个red呢配置们复制过来,我们接下来呢,就使用它来进行一个获取,CTRLV复制过来,这是我们red呢配置,我们给容器中放一个reddi的客户端,这个客户端呢连线我们的虚拟机的reddi,我们以后的所有分布式锁,分布式信号量都是通过这个客户端获取,所以我们来到我们的秒杀业务里边来看我们的这个秒杀业务,当我们来都准备好商品的这个随机码信息以后,那接下来就要准备它的分布式信号量,因为我们扣库存要用它扣,所以呢,我们现在来准备一个叫reddi的这个client,好,我们这个reddi client那容器中呢,已经注。
12:35
录了来写一个owa,我们拿到这个C以后呢,来往下翻,那现在准备好了商品的随机码,然后呢,我们利用它,我们有一个东西叫simple,这是我们的信号量,所以呢,我们可以让它去red里边得到一个信号量,那这个信号量呢,是这么来得的,我们来准备上一个我们的前缀,我们的final string。
13:00
我们是咱们这个SQ的商品库存的这个信号量,我们就叫SQ simple,好,那现在呢,是skto SQ的库存信号量,它的这个S。那么这个信号量呢,我就来写一下SIM,好,我们现在这个信号量它呢就是来每一个商品都有它的这个库存信号量的,我们就叫second kill,我们秒杀有一个叫库存,库存呢后边这块接的就是商品的ID,所以我们现在呢,不应该是商品ID,我们后边接的是加商品随机嘛,商品随机嘛,如果是ID拿ID口,那肯定不行,所以我们现在呢,来找到我们的这个分布式信号量,信号量的这个前缀,再来加上我们的这个随机码,每一个商品呢,都有它固定的自己的随机码,然后得到这个随机码以后。然后我们再来给它设置它的这个信号量到底值有多少,我们有一个sample法,点一个我们要设置这个信号量,所以我们写一个try set promise来设置一个信号量,信号量有多少呢?那有我们这个商品库存有多少,我呢就给你放多少的信号,你只要一个秒杀进来,那就减一个信号什们商品的库存,那就当前SQ,那想要秒杀的这个库存信息,那在这个redq里边,那就是secondqsq VO点一个我们有一个秒杀的库存,就在这count我们这个级数,那就是呢,商品的秒杀件数,商品可以秒杀的数量作为信号量,所以呢,我们在这一块呢,有一个最大的引入,就是引入这个分布式的信号量,那这一块我们都准备好了以后,那就是我们第五步使用咱们这个库存,使用库存作为我们这个分布式的。
14:55
信号量把这些都引入了以后,我们只要秒杀请求一进来,我们你的这个信号量你获取不到了,你都不用执行我们数据库的所有方法了,所以秒杀要做的最大的一个工作,其实就是我们说的限流,我们这个信号量的一大作用,那就是限流,我们只限制这么多信号的流量进来,否则的话呢,都不能执行,那么这个方法呢,全部都准备好,并且把当前秒杀商品的信息那都保存到red以后,那么下一课呢,就来测试一下我们的整个上架功能。
我来说两句