秒杀,想必对于在座的各位一定都不会陌生吧,比如大家在抢购飞天茅台的时候,应该是瞬间被抢购一空了。其实这种场景其实在很多促销情况都非常常见,毕竟明显僧多粥少的情况。那么,今天就由小安来给大家说道说道,秒杀系统背后的奥秘
首先,要知道秒杀的后台为啥难做,因为平时的系统可能面对的并发量就是几百,而秒杀的时候并发量访问量可能增加个几十倍,系统的负荷一下子就上来了。流量太大了。

购买的流程图
这个我们在网站上购买飞天茅台的一整个完整的流程。对于我们后台系统来说,我们主要关注的是具体的一些指标,一个非常重要的指标,就是QPS(Query Per Second),就是一秒的请求量。然后这里还要对一些常用的中间件的性能进行一个补充说明,比如mysql的qps是1000,redis是10w+。
我们在整个系统的设计上面,其实要做到分层解决,就是把每一块都给做好优化,那么整体的性能才会有一个大的提升和优化,具体来说应该怎么做呢。整个服务的链路,我们可以分为浏览器,后台服务,到数据库,3个层次的划分
第一层
浏览器层,这一层我们具体做些什么事呢,我们需要做的就是把一些黑名单还有恶意的链接给阻挡了。另外很多用户可能会进行重复的点击,这样也会平白对我们的后台造成很多不必要的压力,那么我们可以在浏览器按钮对已经按过的开启置灰。另外我们还可以使用js技术对于频繁的点击,给予次数的限制
第二层
主要是服务端的划分,后台的服务我们会不断的进行细化,我们可以划分为秒杀服务,商品服务,订单服务,支付服务等具体的服务,通过把大的服务拆分为小模块,这样的方便我们水平扩展和集群扩展

第三层,这里就是存储层
这一层主要就是存储和访问的,我们这边要做好表的设计,主要就是3张表,一个是秒杀活动表,还有库存表,另外就是商品表。这3张表进行关联。
这边也是我们要突破的关键节点,因为扣库存就在这个环节。因为这边我们会碰到并发的问题,我们初步可以考虑悲观锁和乐观锁
悲观锁

乐观锁

悲观锁因为会占用大量的线程资源,性能浪费太严重。乐观锁因为秒杀并发量太高,也不适合,库存变化过快。
所以我们结合redis重新设计一个整体的方案

这边有几个问题我们需要再次进行考虑
1.什么时候把库存写入redis?
秒杀活动创建/维护的时候
2.如何保证库存和活动数据库一致?
用到分布式事务或者消息队列,分布式事务要几个数据库同时成功才算成功

消息队列,基于消费者生产者的模型,一半有异步任务进行执行,这样可以把消息进行慢慢的处理,主流的中间件有kafka和rabbitma等,主要是异步进行处理
3.下单如何扣减库存?
下单锁定库存,付款扣库存
4.防止超卖?
主要利用redis的院子特性只有一个线程操作
5.库存写回机制?
采用定时任务写会数据库