大白话聊聊秒杀系统的优化思路

1,202 阅读4分钟
        目录

       1、秒杀业务的难点

       2、秒杀业务的优化方向

       3.  常见的秒杀架构

       4.  秒杀业务的各层次优化细节

大家好,我是四九城最豪横的小耳朵。

今天咱们来用大白话聊聊秒杀系统的优化思路。

1、 秒杀业务的难点 常见的秒杀场景:

京东、淘宝上手机商品的秒杀场景,可能手机只有10部,但瞬时进入的流量可能是几百、甚至几千万。

12306抢票场景,票是有限的,库存只有一份,但是瞬时流量非常多,都去读相同的库存。会造成读写冲突,锁异常严重,这是秒杀业务难的地方。

2、秒杀业务的优化方向 那怎么去优化呢?

(1)将请求尽量拦截在系统上游,不要让锁冲突落到数据库上去。传统秒杀系统之所以挂,是因为请求都压倒了后端数据层,数据读写锁冲突严重,并发高响应慢,几乎所有请求都超时,流量虽大,但是下单成功的有效流量甚小。比如我们常见的购票软件12306,一列火车其实只有2000张票,200w个人来买,基本没有人能买成功,请求有效率为0。

(2)充分利用缓存。秒杀买票,这是一个典型的读多写少的应用场景,大部分请求是车次查询,票查询,下单和支付才是写请求。一趟火车其实只有2000张票,200w个人来买,最多2000个人下单成功,其他人都是查询库存,写比例可能只有0.1%,读比例却占99.9%,这种场景非常适合使用缓存来优化。

3、常见的秒杀架构 常见的站点架构业务如下:

浏览器/手机 -----> 服务 -----> 数据

(1)浏览器/手机端,最上层,会执行到一些JS代码或安卓代码,发送请求给站点 (2)服务层,向上游屏蔽底层数据细节,提供数据访问 (3)数据层,最终的库存是存在这里的,mysql是一个典型

4、秒杀业务的各层次优化细节

第1层:浏览器层、APP层优化

(1)产品层面,用户点击“查询”或者“购票”后,按钮置灰,禁止用户重复提交请求;

(b)JS层面,限制用户在x秒之内只能提交一次请求;

APP层面,可以做类似的事情,虽然你疯狂的在摇微信,其实x秒才向后端发起一次请求。这就是所谓的“将请求尽量拦截在系统上游”,越上游越好,浏览器层,APP层就给拦住,这样就能挡住80%+的请求。

第2层 服务层优化

服务层怎么拦截?如果已经清楚的知道秒杀的手机只有100部,一列火车只有2500张车票,那么你放10w个请求去数据库又有什么意义呢?这种场景下可以使用请求队列来解决。对于写请求,做请求队列,每次只透有限的写请求去数据层。

比如100部手机,只透100个下单请求去db

2500张火车票,只透2500个下单请求去db

如果均成功再放下一批,如果库存不够则队列里的写请求全部返回“已售完”。

对于读请求,怎么优化?可以用缓存抗,redis单机抗个每秒10w完全没什么问题。

这种限流方案,只有非常少的写请求,和非常少的读缓存的请求会透到数据层去,而99.9%的无用请求被拦住了。

当然,业务规则上也可以做一些优化。比如12306的按时间段放票,可以将流量摊匀。

还有,数据粒度也可以做优化。比如你去购票,对于余票查询这个业务,票剩了500张,还是300张,你真的关注么,其实我们关心的是有票和无票罢了,流量大的时候,做一个粗粒度的“有票”“无票”缓存即可。

第3层 最后是数据库层

浏览器拦截了90%,服务层又做了写请求队列与数据缓存,每次透到数据库层的请求都是可控的。db基本就没什么压力了,单机也能扛得住。而且通过对第2次服务层的优化,也保证了请求的有效率。

以上,就是秒杀系统的优化思路。

                      End

作者简介:豪横的小耳朵,一个豪横的程序员。想和大家一起在技术的世界里豪横,用技术的眼光去看待世界。欢迎扫描下方二维码,持续关注,一大波原创系列文章正在路上。

关注后回复“666”,可免费获取java高级工程师学习资料一份。