秒杀真那么难?手把手带你优化秒杀流程

天天早上七点三十,准时推送干货

又到周六了,终于又能够休息两天,不过学习还不能中止,今天分享一下星球球友 @楼下小黑哥关于秒杀的分享。web

晚上听了架构师之路沈剑老师的一场关于秒杀业务的直播分享,总结了一下,分享一下给你们。面试

秒杀业务最大的业务特色,短期内,高并发,大量读请求,大量的写请求。若是不经任何优化,直接将所有读写请求打到数据库层,数据库层因为锁冲突,特别是热点数据行锁冲突,很容易形成死锁,下降数据库执行效率。并且流量很大的状况,很容易将会把数据库压死。数据库层若挂了,若是再次启动,极可能又会被大流量再次压垮。数据库

从系统的角度来看,在秒杀业务的状况下,咱们要保护数据层的安全。浏览器

为了保证数据库的安全,咱们就要下降最后到达数据库层读写流量,使其一直处于安全的状况下运行。缓存

从读写方向,优化思路:安全

  • 降读
  • 降写

下降数据层读请求,主要办法就是加缓存,数据优先读取缓存,缓存不存在再从数据库层读取。缓存解决办法比较多,下面主要介绍降写的处理办法。服务器

下降数据层写请求,咱们就必须在上游应用层过滤写清求。微信

技术优化手段

假设咱们的系统架构以下:网络

网站/APP---->站点接入应用------>后台服务---->数据库层架构

咱们能够在这三层作优化,拦截写请求,下降数据层写压力。

在网站/APP 层,咱们可使用 JS 等手段,防止用户重复点击。

不过这种手段只能预防普通用户,高级用户能够经过抓包获取请求接口,经过程序发起,绕开 JS。

因此咱们须要在站点接入层经过计数的方式,防止同一用户频繁发送请求。好比咱们能够限制同一用户每 5 秒,只有一次请求才有效,其他请求返回请求速率过快。

站点层只能限制单一用户,能够经过多用户手段绕开这一限制。

等到写请求到达服务层,服务层能够发送到 MQ 队列或者内存队列,而后根据库存数量,或者数据库抗压能力处理。

好比说某件商品库存只有 2000 个,这时服务层现收到 2 w 个写请求,所有发送到队列中。假设数据库层只能最大只能处理 1000 个写请求,那咱们消费程序就拉取 1000 条消息,真正进行数据写请求。

写入成功以后,再次消费消息,直到库存为 0 。这时剩下的消息,都无需再执行数据库的写请求。

产品手段

除了上述的技术手段以外,咱们还能够在产品设计方面减小写请求。

咱们能够在页面使下单按钮置灰,防止重复点击。

咱们还能够页面是不显示库存具体数量,只显示库存的是否还有,下降缓存的淘汰率。

咱们还能够将下单与支付流程分离,下单成功后,才能去支付。这时支付系统的压力就很小不少。

相关问题

站点层服务压力很大的处理方案

在咱们上面的方案中,站点接入层须要计数过滤,压力可能会很大。因为站点接入层通常都是无状态应用,能够水平扩展。因此咱们能够适当增长机器,增长处理能力。

另外,咱们还能够设置必定阈值,等请求到达阈值以后,服务降级,抛弃后续请求。

计数问题

计数咱们能够存储在 Redis 中,若是 Redis 性能不够,咱们能够水平扩展,使用相似 Redis Cluster 方案。

Redis 吞吐量很大,若是惧怕网络带宽成为瓶颈,咱们能够考虑不使用 Redis ,直接在内存中计数,不过这种方案就须要考虑数据一致性。

若是使用内存计数,同一用户的请求就必须落在同一台机器上。这里的处理的方案咱们能够在 Nginx 层使用 用户 ID 切分,而后在分发到的站点接入层。

另外使用内存计数,咱们下降数据的一致性与准确性,容许因业务重启,致使内存的丢失的状况。

队列异步处理,浏览器/APP处理方式

1.在请求发送到队列中时,咱们能够提早预分配一个订单号,消息发送成功,将订单号返回给页面

2.浏览器/APP 拿到订单号返回以后,跳转到中间也,而后定时轮询。页面咱们能够提示用户,订单正在排队中,若刷新将会再次进入排队,防止用户再次刷新下单。



< END >

若是你们喜欢咱们的文章,欢迎你们转发,点击在看让更多的人看到。也欢迎你们热爱技术和学习的朋友加入的咱们的知识星球当中,咱们共同成长,进步。




往期 精彩回顾




面试官:生产服务器变慢了,你能谈谈诊断思路吗
面试官提问:如何去掉list集合中重复的元素?
引入两个依赖以后,阿粉一周内就完成了网站的登陆改造|实战开发


本文分享自微信公众号 - Java极客技术(Javageektech)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索