面试官问到秒杀系统时这样回答! -- 2022-03-04

哈喽,大家好!我是指北君!

不管是面试中,或者是日常的工作学习中,我们会以支持高并发为目标。来获的自身开发能力的提高,以可以处理高并发的情况来表达自己的开发水平。

1. 如何设计一个秒杀系统

想要理解秒杀系统,需要先了解一下秒杀系统的业务背景。

下面举例一个通用的业务场景: 在某个时间点,某某电商网站要低价卖某件商品,而且限量1千件,抢购人数超过数十万人。

由于秒杀的特点就是时间极短,然后瞬间流量非常大。

然而就算存在这些问题呢,我们的系统也需要保证秒杀抢购的结果不出错,达到抢购的预期目的。

而且秒杀库存的实现也需要保障秒杀结果的准确性。

总结几个特点就是:

  • 高性能: 秒杀中有大量的并发读写,所以需要使系统能支撑起高并发访问,这是一个关键点。
  • 高可用:藐视瞬间流量非常大,很有可能会导致系统宕机,所以需要从各方面保证系统的可用性。
  • 一致性:由于秒杀请求量非常大,此时就需要我们的秒杀结果要准确。因为一旦出错,那么波及面会非常广,损失非常大。

2. 描述一个秒杀流程

我们从秒杀入口开始说说。

在秒杀入口的地方会有这些问题需要解决,

2.1 前端处理

静态资源处理

秒杀商品一般都会包含很多静态资源,所以这些图片什么的静态资源一定要放到CDN,能放的尽量放进去。让秒杀时后端服务器的压力尽可能小。

恶意访问行为的处理

各大商家推出各种秒杀活动,黄牛党们也会开发出各种秒杀器,可以自动填单,自动回答各种问题,以及自动模拟点击等,令商家防不胜防。

针对这些各大电商也做了各种工作来限制和识别这些恶意访问。例如限制IP的提交次数,提高各种动态验证码及问题的难度,增加黑名单账户等。

秒杀链接隐藏

如果稍微懂点程序的人可以提前拿到秒杀链接,那么就可以通过程序在最快的时间发起秒杀请求,这样人家就可以拿到大部分商品了。 为了防止这一点,可以使秒杀链接动态化。使用MD5算法等加密随机字符串作为URL的一部分,秒杀开始后才将连接放出来,同时在后台进行校验,此时已经可以防止一大批的羊毛党了。

前端限流

可以在秒杀按钮点击之后灰掉几秒钟,几秒钟之内只能点击一次。

可以使用Nginx用户请求到Nginx的时候将流量分散到多个服务器上,而且也可以针对用户进行一些过滤,将一些请求拦截,保证后端的稳定性。比如1万个商品,最多放进来10万个请求就可以了,其他的用户就只能等着静态页面喽。同时也可以在秒杀预约的时候随机发放一些token,只有拥有这些token的客户才有可能抢购成功。

2.2 后端处理

后端限流

秒杀的时候,如果有商品1万件,1百万请求,其实只有1万的请求可以成功,那么我们可以只放10万请求进到后端,服务器的压力也会相对减少。

降级&熔断&隔离

如果服务的流量到达最大值的时候,新的请求就不能再进来了。

而服务宕机的时候也需要引导请求到备用服务器上面,然后返回一些静态提示页面等。

隔离就要求,秒杀的服务单独部署,只承担其秒杀的单一职责,即使出问题,也不会影响其他的服务。

削峰

秒杀流量在某一个时间点非常高,那么我们让瞬间进来的流量进到一个缓冲池,然后再进行平缓处理。比较多用到的方案就是使用消息队列来处理。

库存预热

由于秒杀的商品的数量一般都是提前已知的,这时我们可以提前将商品的一些数据提前加载到缓存中。并且可以将商品分区来进行秒杀,根据每个大区的用户数量以及活跃程度,为每个大区分配单独的秒杀商品数量。这样也可以分散服务器压力。

使用缓存

高并发的情况下必然会遇到缓存雪崩,缓存击穿,缓存穿透等问题。而且秒杀的场景是读多写少,使用Redis作为缓存非常合适,为了避免单台Redis服务器出问题,导致缓存击穿等问题,升级使用Redis集群是一个比较好的方案。提升可用性的同事性能也可以大大提高。

超卖问题

秒杀中一个重要的点就是超卖问题,由于抢购人数多,流量也很大,但是也不能卖多了,不然老板提刀和你商量。

网上比较多的方案有:

  1. 数据库要加唯一索引,减库存的时候要先进行库存数量判断等,数据库锁,加版本号的乐观锁方式等等。
  2. 采用Redis来维护库存,由于秒杀活动可以预先知道商品的数量,所以可以提前将商品的数据加载到Redis中,如果Redis的库存不足的话则秒杀失败。
  3. 生成订单的时候将请求放到服务端的异步队列中去处理,可以使用Redis的队列,或者一些MQ均可。

#####

3 总结

其实秒杀方案的总体思路也很简单:

  • 尽可能的将请求拦截在上游
  • 前后端均要处理限流
  • 尽量减少请求到数据库
  • 多利用缓存
  • 使用异步操作-可以使用队列等
  • 秒杀服务单一职责
  • 尽早失败,让秒杀请求返回
Java Geek Tech wechat
欢迎订阅 Java 技术指北,这里分享关于 Java 的一切。