秒杀系统设计
设计1
秒杀系统时序图
同步下单流程
1.用户发起秒杀请求
在同步下单流程中,首先,用户发起秒杀请求。商城服务需要依次执行如下流程来处理秒杀请求的业务。
(1)识别验证码是否正确
商城服务判断用户发起秒杀请求时提交的验证码是否正确。
(2)判断活动是否已经结束
验证当前秒杀活动是否已经结束。
(3)验证访问请求是否处于黑名单
在电商领域中,存在着很多的恶意竞争,也就是说,其他商家可能会通过不正当手段来恶意请求秒杀系统,占用系统大量的带宽和其他系统资源。
此时,就需要使用风控系统等实现黑名单机制。为了简单,也可以使用拦截器统计访问频次实现黑名单机制。
(4)验证真实库存是否足够
系统需要验证商品的真实库存是否足够,是否能够支持本次秒杀活动的商品库存量。
(5)扣减缓存中的库存
在秒杀业务中,往往会将商品库存等信息存放在缓存中,此时,还需要验证秒杀活动使用的商品库存是否足够,并且需要扣减秒杀活动的商品库存数量。
(6)计算秒杀的价格
由于在秒杀活动中,商品的秒杀价格和商品的真实价格存在差异,所以,需要计算商品的秒杀价格。
注意:如果在秒杀场景中,系统涉及的业务更加复杂的话,会涉及更多的业务操作,这里只是列举出一些常见的业务操作。
2.提交订单
(1)订单入口
将用户提交的订单信息保存到数据库中。
(2)扣减真实库存
订单入库后,需要在商品的真实库存中将本次成功下单的商品数量扣除。
如果使用上述流程开发了一个秒杀系统,当用户发起秒杀请求时,由于系统每个业务流程都是串行执行的,整体上系统的性能不会太高,当并发量太高时,会为用户弹出下面的排队页面,来提示用户进行等待。
异步下单流程
1.用户发起秒杀请求
用户发起秒杀请求后,商城服务会经过如下业务流程。
(1)检测验证码是否正确
用户发起秒杀请求时,会将验证码一同发送过来,系统会检验验证码是否有效,并且是否正确。
(2)是否限流
系统会对用户的请求进行是否限流的判断,这里,可以通过判断消息队列的长度来进行判断。因为将用户的请求放在了消息队列中,消息队列中堆积的是用户的请求,可以根据当前消息队列中存在的待处理的请求数量来判断是否需要对用户的请求进行限流处理。
例如,在秒杀活动中,出售1000件商品,此时在消息队列中存在1000个请求,如果后续仍然有用户发起秒杀请求,则后续的请求可以不再处理,直接向用户返回商品已售完的提示。
(3)发送MQ
用户的秒杀请求通过前面的验证后,就可以将用户的请求参数等信息发送到MQ中进行异步处理,同时,向用户响应结果信息。在商城服务中,会有专门的异步任务处理模块来消费消息队列中的请求,并处理后续的异步流程。
在用户发起秒杀请求时,异步下单流程比同步下单流程处理的业务操作更少,它将后续的操作通过MQ发送给异步处理模块进行处理,并迅速向用户返回响应结果,释放请求连接。
2.异步处理
可以将下单流程的如下操作进行异步处理。
(1)判断活动是否已经结束
(2)判断本次请求是否处于系统黑名单,为了防止电商领域同行的恶意竞争可以为系统增加黑名单机制,将恶意的请求放入系统的黑名单中。可以使用拦截器统计访问频次来实现。
(3)扣减缓存中的秒杀商品的库存数量。
(4)生成秒杀Token,这个Token是绑定当前用户和当前秒杀活动的,只有生成了秒杀Token的请求才有资格进行秒杀活动。
这里引入了异步处理机制,在异步处理中,系统使用多少资源,分配多少线程来处理相应的任务,是可以进行控制的。
3.短轮询查询秒杀结果
这里,可以采取客户端短轮询查询是否获得秒杀资格的方案。例如,客户端可以每隔3秒钟轮询请求服务器,查询是否获得秒杀资格,这里,在服务器的处理就是判断当前用户是否存在秒杀Token,如果服务器为当前用户生成了秒杀Token,则当前用户存在秒杀资格。否则继续轮询查询,直到超时或者服务器返回商品已售完或者无秒杀资格等信息为止。
采用短轮询查询秒杀结果时,在页面上同样可以提示用户排队处理中,但是此时客户端会每隔几秒轮询服务器查询秒杀资格的状态,相比于同步下单流程来说,无需长时间占用请求连接。
此时,可能会有网友会问:采用短轮询查询的方式,会不会存在直到超时也查询不到是否具有秒杀资格的状态呢?答案是:有可能!
这里试想一下秒杀的真实场景,商家参加秒杀活动本质上不是为了赚钱,而是提升商品的销量和商家的知名度,吸引更多的用户来买自己的商品。所以,不必保证用户能够100%的查询到是否具有秒杀资格的状态。
4.秒杀结算
(1)验证下单Token
客户端提交秒杀结算时,会将秒杀Token一同提交到服务器,商城服务会验证当前的秒杀Token是否有效。
(2)加入秒杀购物车
商城服务在验证秒杀Token合法并有效后,会将用户秒杀的商品添加到秒杀购物车。
5.提交订单
(1)订单入库
将用户提交的订单信息保存到数据库中。
(2)删除Token
秒杀商品订单入库成功后,删除秒杀Token。
这里大家可以思考一个问题:为什么只在异步下单流程的粉色部分采用异步处理,而没有在其他部分采取异步削峰和填谷的措施呢?
这是因为在异步下单流程的设计中,无论是在产品设计上还是在接口设计上,在用户发起秒杀请求阶段对用户的请求进行了限流操作,可以说,系统的限流操作是非常前置的。
在用户发起秒杀请求时进行了限流,系统的高峰流量已经被平滑解决了,再往后走,其实系统的并发量和系统流量并不是非常高了。
所以,网上很多的文章和帖子中在介绍秒杀系统时,说是在下单时使用异步削峰来进行一些限流操作,那都是在扯淡!因为下单操作在整个秒杀系统的流程中属于比较靠后的操作了,限流操作一定要前置处理,在秒杀业务后面的流程中做限流操作是没啥卵用的。