面试对线记录8 如何设计一个秒杀系统
今天和面试官二轮对线时碰到了这个问题,害,我是个菜狗,Java实在是太小白了,当时只是说出了几个点,但是应该说的都不对,所以开个帖子仔细整理一下。 不管是完成一个系统还是完成一个功能,肯定要提前做好分析,然后罗列出所有开发和设计中可能遇到的的问题点,然后根据问题点找到解决方案,接下来设计架构,根据架构进行开发和检测,我认为一个开发应该是这样子的。 so经过我网上遍寻资料以及整理,我觉得一个秒杀系统遇到的问题有以下几点:
-
高并发:既然是秒杀系统,那肯定是千军万马在一秒间过独木桥,所以系统如何扛得住高并发的请求;
-
超卖:怎么防止某个商品卖超了;
-
接口防刷:这个就涉及安全了,现在网上到处都是各种连点器,秒杀脚本等等各种奇怪的软件,目的就是为了代替人来抢某个商品,所以遇到这种刷单问题怎么解决;
-
秒杀url可见 这是目前我能想到的一些问题,首先在这之前,我觉得要考虑一个问题,我们现在考虑的是如何把一个秒杀系统维持住的问题,换句话说就是如何实现一个秒杀系统业务的问题,but我们没有考虑一个问题,如果秒杀系统被玩的不好,出现缓存雪崩,缓存击穿,缓存穿透等等情况,巨量的流量直接打在数据库上,数据库服务器boom了,所有的后台服务一起挂掉了。。。我们肯定不能连带其他业务一起挂,所以以上考虑的前提就是先提前分库分表,gg也不能大家一起gg。
-
接口防刷
- 面对可见url的问题,因为有些稍微懂一点点技术的老铁都知道在chorme中可以看到前端的接口,所以我们在设计秒杀接口的时候一定要注意秒杀接口的可见性,不能在秒杀系统开始之前就有一堆人用程序来刷接口,所以在秒杀时间开始前,不能拿到秒杀接口,只有秒杀开始时,才返回秒杀地址和验证MD5,用户拿到这两个数据才可以进行秒杀;
- 如果多个账号在一个ip地址发出多个请求,我们可以在设计系统时检测ip请求频率,如果超过某个阈值,那么就弹出验证码或者其他东西进行验证;
- 当然最多的情况是一个账号发出多个请求,我们可以限定这个用户在发起一次秒杀后,需要等待才可以发起另一次请求,从而减少多个请求的压力,或者使用redis标志位,每个用户的请求都尝试在Redis中插入一个secondKill的标志位,成功插入的才可以执行后续的秒杀逻辑,其他的就被过滤掉。
- 当然还有多个账号不同ip发起不同请求,我们可以采用检测账号等级的或者检测性别的骚操作来减少操作。。。
- 前端进行优化的话,可以采用验证码,降低用户的请求速度,或者采用限购的策略,抢到一个商品后,不能再抢第二个,或者说将前端静态数据缓存在离用户最近的地方,比如用户浏览器,CDN或者服务器的缓存中。 2.超卖问题
- 缓存预热 在秒杀之前,需要将秒杀商品信息提前缓存到Redis中,这么秒杀开始时就直接从Redis读取,也就是缓存预热。