本文是新系列“实战高并发”的开篇做。这个系列做为“我说分布式”的子系列,将着重挑选若干典型的分布式实战场景,尽可能对当下高并发领域较为热门的架构及业务场景作一次较为深刻的实践与总结。前端
该系列既是对笔者接触过的业务的整理,也但愿系列中分享的套路可以对读者朋友解决实际业务中面临的问题有所帮助。git
言归正传,本文我将主要从业务场景及技术架构等方面出发,对”电商高并发秒杀”这一业务场景作一次较为全面的阐述,同时做为后续实操的开发设计依据。github
“秒杀”这一业务场景在现在已经不是什么新鲜名词,它本质上属于短时突发性高并发访问问题,业务特色以下:面试
分析一下这些秒杀场景的典型特色,咱们不难看出,秒杀场景属于典型的高并发场景,对系统的冲击较大。咱们来对上述特色进行逐一分析:后端
这不难理解,秒杀活动每每伴随着固定的节日、活动而开展,在某一个肯定时间对C端用户开放访问能力,此时每每会出现一个较为明显的请求激增。如:每一年“双11”当天0点,淘宝等电商平台访问量基本上会出现明显的请求波峰,这与秒杀的定时性,息息相关。缓存
这是确定的,在库存有限、请求接收较多的状况下,常会存在部分请求处理成功,部分请求处理失败的状况。性能优化
若是库存是无限的,也就不存在秒杀这一说了。也正是由于库存有限,平台以此为卖点,采起定时限量售卖的营销策略更能刺激用户进行访问。架构
通常状况,秒杀场景下的商品售价较平时都有明显的优惠。并发
商品数量有限在上文已经说过了,咱们聊聊“超卖”、“少卖”的问题。异步
超卖是不能容忍的状况,若是发生超卖,则属于业务异常了。通常状况下商家只会提供有限数量的商品做为秒杀营销商品,若是超卖,则商家每每面临较为明显的亏损。这在业务上是不能出现的。
少卖则是可以接受的,好比商家提供了10台IPhoneX做为秒杀库存,因为临时减库存或其余缘由(每每都是业务上的缘由)调整只卖了9台。这对商家而言并无多大的损失,商家还能够以更高的价格去售卖该多余库存,并且平台由于该秒杀活动还收获了较高的PV/UV,整体而言是没有损失的。
所以咱们在设计秒杀架构的时候要以 “超卖零容忍,少卖能兼容” 这一设计原则进行设计。
因为秒杀业务的特殊性–短时超高并发,所以咱们不能按照传统的交易场景进行设计。
传统交易场景下,对于用户的下单请求通常都是同步处理,即同步落库持久化,并同步返回收单结果。
若是咱们对秒杀订单采用同步持久化的作法,则系统的吞吐量将基本依赖DB的性能,这在成本上、性能上都有较大压力。所以,咱们要在尽可能提升系统收单入口吞吐量的同时下降系统开发部署的成本。
“不要求当即返回真实下单结果”,也就是不须要当即持久化,换言之也就是业务流程 “异步化” 。
明确了流程能够异步化,解决的手段就多了。利用缓存、队列、线程池都能实现业务的异步化。这里也反映出
技术是围绕业务运转的,没有业务做为支撑,不管技术多么新颖、其性能多么高,它都无用武之地。
经过对秒杀核心业务流程进行异步化,咱们可以将主流程分为收单、下单两个阶段,业务流程归纳起来以下:
到此,对用户侧的交互就告一段落。
下单流程中,平台的压力经过中间层的缓冲其实已经小了不少,之因此会少,一方面是由于在用户下单的同步校验过程当中就过滤掉了部分非法请求;另外一方面,咱们经过在中间层作一些限流、过滤等逻辑对下单请求作限速、压单等操做,将下单请求在内部慢慢消化,尽量减小流量对平台持久层的冲击。这里其实就体现了中间层 “削峰填谷” 的特色。
基于上述前提,咱们简单总结下秒杀下单部分的业务逻辑。
到此,基本上就是秒杀业务的核心主流程。
进一步抽象 秒杀请求->中间层->真实下单 这个场景,是否是很像咱们常常用到的一种异步业务处理模式?
相信有心的你已经看出来了,没错,这就是 “生产者-消费者” 模式。
“生产者-消费者”模式 在进程内,经常经过 阻塞队列 或者 “等待-通知” 等机制实现,在服务之间则每每经过消息队列实现,这也是本次实战所采用的技术实现手段。在后续的实战中,我将经过RocketMQ消息队列,对秒杀下单进行解耦,实现削峰填谷、提升系统吞吐量的目的。此处就很少赘述,到编码部分再详细展开。
看了这么多文字,可能读者朋友仍是有不清楚的地方,那么咱们就经过图解的方式来对流程进行更加直观的理解。
详细细节在上文中的描述部分已经作过阐述,读者朋友能够配合一块儿看,这里只对图示流程进行简略总结:
1:用户访问秒杀网关seckill-gateway-service,对感兴趣的商品发起秒杀操做。特别的,对于商品信息,在系统初始化的时候已经加载到seckill-gateway-service。在进行前置库存校验的时候,依据缓存已经作了一次用户下单流量的过滤。
2:网关对秒杀订单进行充分的预校验以后,将秒杀下单消息投递到RocketMQ中,同步向用户返回排队中
3:秒杀订单平台seckill-order-service订阅秒杀下单消息,对消息进行幂等处理,并对商品库存进行真实校验后,进行真实下单操做
咱们本次实战主要关注 收单、下单 这两个核心场景,对于后续的支付及通知不作涉及,更多的关于下单通知场景,在后面的实战系列会逐步的进行呈现。
本流程为用户经过秒杀网关seckill-gateway-service提供的查单接口对本身下的秒杀订单进行查询跟踪。
本文为“实战分布式之电商高并发秒杀”的首篇,主要介绍了秒杀的业务特色及实现的思路,经过图文配合的方式对 “秒杀” 这一高并发典型场景作了较为全面的阐述。
因为咱们的重点在于秒杀的核心场景,所以仍是存在有待优化的细节。此处一并罗列一下,做为后续参考:
1:推荐采用分布式减库存策略:如:使用Redis的decr进行原子减库存。
2:预热库存时,将库存适当调大,防止恶意刷库存致使正经常使用户不能进行秒杀下单请求。这里要注意只调整缓存中的库存,不能调整商品库中的真实库存,不然会出现 “超卖” 从而致使损失。
3:秒杀接口须要作防刷处理,能够在前端页面经过倒计时方式定时开放接口;经过增长验证码减小下单频率;经过增长下单前收货地址校验、实名认证等方式对僵尸用户进行拦截。
PS:本次实战主要从后端实现部分出发进行设计,所以对于前端部分的设计与注意点只作简单概述,恕不展开。
项目完整源码地址:
在此我向你们推荐一个架构学习交流群。交流学习群号:833145934 里面资深架构师会分享一些整理好的录制视频录像和BATJ面试题:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多。