秒杀抢购系统的成功平稳运行,有一些需要注意的知识点。

1 高并发,以及刷接口等黑客请求对服务端的负载冲击

2 高并发时带来的超卖,即商品数量的控制

3 高负载下,下单的速度和成功率的保证

4 其他

以秒杀单品为例,如抢小米手机。

解决方案探讨:

第一步 限制前端发来的请求量

譬如定在了周二10点开启抢购,那么在之前的一周时间内,都会有预约通知,或者普通的用户浏览。通过预约量、浏览量等数据分析,大概能预估到在周二会参与“点击抢购按钮”的人数。譬如有500万。

此时,我们是知道实际商品数量的,譬如20万。

那么我是没有必要让这500万个请求都到后台的,我最多最多放200万个请求到后台。其他的300万直接就在前端网页看单机动画就好了。

这一步做起来很简单,20万个商品,我提前生成200万个token,在用户点击预约、或者浏览该商品时,就按规则发放出去。(规则可以是譬如公平模式,某个用户id已经预约多次了,还没抢到,那么给他token。也可以就是随机发放,5天的预热时间,每天发4万个就好)

前端接收到是否能参与秒杀的反馈后,就保存在浏览器本地就好,当秒杀开始时,没得到token的用户,就只好在本地看单机动画,过几秒告诉他商品不足就好了。

那些幸运的得到了token的用户,就有了给后台发请求参加秒杀的机会了,此时还需要前端(APP客户端)来对请求进行控制,因为用户喜欢反复点击、反复刷新页面等手段来参加抢购,这时就不能再放重复请求进后台了,哪怕是他重复点击了,也要保证请求不反复发送。

对于大部分吃瓜群众来说,只会操作页面的就通过这种方式控制,但对于程序员们就不行了,即便是你在抢购开始前,没有暴露抢购的接口,但在抢购开始的一瞬间,他们依旧能搞到你的下单接口地址,并开始用程序频繁提交下单请求。

第二步 由网关限制程序过量请求

用程序下单对程序员们都懂,拼接好请求的各个参数,开启并发提交到服务器。

到了这一步,已经不归前端管了,请求会直达负载均衡器,然后到后台网关。

在网关里要控制好这部分请求,要以最快的速度判断出来的每一个请求是否放行到后面的服务。

网关的实现方案有很多,kong(nginx+lua),Gateway,zuul等。在网关里可以简单的实现限流机制,我们主要限制的有如下几种:

1 黑名单(ip、用户id等),可以直接放内存里

2 过多的重复请求(可以采用redis集群计数,对同一个ip、id发起的重复请求给予拒绝),考虑到redis的带宽、性能瓶颈,可以考虑做分片,或者做二级缓存,直接在jvm内存里统计计数

3 没有token的请求,就是之前放出去那批token

限制了非常规请求后,我们假如还有100万个请求在2秒内打到了服务端,这依旧是非常恐怖的数字,即便你有10台服务器,还是有大概率被打满CPU,后面的请求就有面临5秒超时的风险。

此时,我们要做的就是尽快处理完前面的请求,把商品赶紧卖光。100万个请求,20万个商品,那肯定是不能让那80万请求去触碰下单的服务的,我们要在网关处就终结掉这80万个请求,给他们交代你来晚了。

此时你需要令牌桶,如guava的rateLimer就可以,简单好用。譬如我有20个zuul网关服务在运行,单个服务要承担5万个请求,单个tomcat在不做复杂计算、不做数据库操作,做到1-2千的QPS还是可以的。

我每一个zuul服务里譬如开辟1.5万个令牌桶,在1-3秒内放完,得不到令牌桶的就直接返回失败就行了。在这一步失败的耗时会很短,因为在网关层就失败了,不会进入到后面的下单流程。

请注意,这一步是没有用消息队列的,因为大部分请求是要被拒绝的,需要尽快的返回拒绝信息,进队列再慢慢消费就慢了。

令牌桶签发完毕,剩下的请求都是幸运儿,就可以进入到后面的下单流程了。

第三步 极速下单

下单是另外的服务,由zuul将请求转发到这里,那么以最快的速度生成订单将非常重要,不然又是大量超时。

此时数据库是指望不上了,数据库一秒2千的写入都已经比较艰难,即便是集群,想要达到万的量级也是比较困难,等你入库完毕,都半分钟过去了。

那么下单到哪呢,首选redis。你在订单请求到达后,迅速拼接好order、orderItem对象,将订单下到redis里。考虑到redis的压力,可以将redis分片,将不同的用户的订单,下到不同的redis实例中。

下到redis的目的一是速度快,二是为了做订单查询用,因为下单后用户还是要查询订单的,而此时还没有入库。在下单到redis的同时,写入到消费队列MQ中一份,这一步是用来让后端消费,并入库的。入库就可以从MQ里慢慢消费了,再去做那些耗时的入库操作,分布式事务等等。入库成功后,就可以把redis的订单删掉了。

第四步 防超卖

从上面的流程看,我们通过令牌桶放出去的令牌数是大于商品数量的,那么就面临超卖问题。

超卖在分布式环境下,方案就是分布式锁,譬如redisson的分布式锁,可以针对商品id加分布式锁。

问题又出来了,如果商品数量很少,几百几千个,通过分布式锁也能很快的处理完。实测,redis加锁、释放锁耗时约1ms,再加上客户端逻辑处理时间,按下一单要5-10ms(非常急速了),那么一秒在对同一个分布式锁的操作上,也就百单而已。

可以发现,通过对同一个商品id加分布式锁,商品数量巨多时就麻烦了,因为是对商品id加锁,那么上锁解锁这个动作被执行几十万次,时间耗费巨大。

那么这个分布式锁就会有严重的性能问题,就要再次对商品数量进行分片,譬如一个用来分布式锁的redis key,只放500个商品数量,耗完结束,对应这个key的请求就算全部卖光。譬如商品id是10,那么我们就用goodsId-10-1,goodsId-10-2,goodsId-10-3这样,建立count/500个key,当请求来时,按照hash将分布式锁加到不同的key上。这样也能大幅提高分布式锁的性能。

当然这样会造成redis压力巨大,再将redis做个集群也行。总的来说这个方案貌似很复杂,而且很难控制,譬如比较难以控制不同key的余量消耗。

那么太复杂的方案就还是抛弃。我们直接在服务实例里写商品数量,这样直接在内存里判断商品剩余量,谁也不通信了,性能达到极致。

譬如我们部署了20个订单实例,20万个商品,我们将服务接入配置中心(Apollo,disconf,nacos之类的),通过配置中心来下发每个实例的商品数量,而且可以动态控制。可以在抢购开始前,通过配置中心下发到每个服务1万个商品数量,当这个实例将内存里的商品数量消耗完毕,就算售罄。当然,由于服务的处理速度,和请求的不均匀,可能导致某个实例早早售罄,别的实例还有大量剩余。也就是在页面上比你晚的人,来了还能买到,而你早早售罄了。那就不要怪程序员了。

要是中途个别实例挂掉了怎么办?挂掉了我们就不管它了。不要为它再设置什么复杂逻辑了。大不了少卖一些而已。既然是售罄,卖20万个,和卖了19万3千个,也没什么区别。可以等其他实例全卖光后,统计一下redis的订单数量,譬如卖了19万个3千,再把它启动起来,设置个7000的剩余量,这样也行。但这不重要了。可以将这部分放到30分钟后,没付款的被丢回库存池里再卖也一样。

————————————————
版权声明:本文为CSDN博主「天涯泪小武」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tianyaleixiaowu/article/details/102524667

关于电商秒杀系统中防超卖、以及高性能下单的处理方案简述相关推荐

  1. 关于电商秒杀系统中防超卖处理方案简述,统统给你解决!

    一.Spring Boot 相关 (1)SpringBoot 面试专题 什么是 Spring Boot? Spring Boot 有哪些优点? 什么是 JavaConfig? 如何重新加载 Sprin ...

  2. 电商秒杀系统相关实现

    前言 本文主要就电商秒杀系统所涉及的相关技术进行探究,相关Demo地址如下: 个人实现版本:https://github.com/MrSorrow/seckill Github Star较高的版本,第 ...

  3. 电商库存锁_解密 Redis 助力双 11 背后电商秒杀系统

    作者:AlibabaCloud 来源:https://github.com/AlibabaCloudDocs/kvstore/blob/master/cn.zh-CN/最佳实践/使用%20Redis% ...

  4. Java电商秒杀系统性能优化(一)——电商秒杀系统框架回顾

    电商秒杀系统框架回顾 项目简介 外部依赖 框架回顾 项目要点 项目中存在的问题 小结 课程是免费的,课程地址如下:SpringBoot搭建电商秒杀项目,课程真的很棒,作者的思路很清晰,建议各位读者可以 ...

  5. 毕业设计-电商秒杀系统

    目录 1.业务背景 2.基本场景 3.重点场景分析 3.1.浏览秒杀商品 3.2.下单 4.存储架构设计 5.计算架构设计 5.1.负载均衡 5.2.多级缓存 6.高可用设计 7.可扩展设计 8.高可 ...

  6. Java实现电商秒杀系统-jseckill

    1.前言 什么是秒杀?双十一,双十二天猫京东优惠大促销,大量的用户去抢夺少量的商品,在段时间内抢完,称之为秒杀.典型的高并发应用场景. 2.简介 电商秒杀系统,要求并发量特别大,用Java实现秒杀系统 ...

  7. 万字好文,电商秒杀系统架构分析与实战

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 后台回复"k8s",可领取k8s资料 1 秒杀业务分析 ...

  8. 万字好文,电商秒杀系统架构分析与实战!

    1 秒杀业务分析 正常电子商务流程 (1)查询商品:  (2)创建订单:  (3)扣减库存:  (4)更新订单:  (5)付款:  (6)卖家发货: 秒杀业务的特性 (1)低廉价格:  (2)大幅推广 ...

  9. 电商秒杀系统设计分析

    1,乐视秒杀,每秒钟10万的订单更新(insert/update),以用户ID分库分表,二叉树分库扩容,表级同步,DB1 - DB8, order1 - order10, DB编号 = (uid/10 ...

最新文章

  1. pdf文件之itextpdf插入html内容以及中文解决方案
  2. php系统升级说明,PHPCMF内容管理框架 v4.2.7 升级说明
  3. 接口 Closeable
  4. fusion构建器代码语法_构建器模式:适用于代码,适用于测试
  5. c语言文件指针ab命令,C语言试题,~库(完整版~).doc
  6. leetcode110. 平衡二叉树(递归)
  7. 中绘制折线_统计图之折线图的结构和制作过程
  8. 【Golang】关于从切片中删除某个元素时会覆盖底层数组的说明
  9. 如何安装和_彻底卸载MySQL
  10. 基于51单片机毕业设计 开题选题
  11. 关于 Failed to resolve: org.jetbrains.kotlin:kotlin-stdlib-jre7的错误
  12. 用例图之参与者、用例间的四种关系
  13. Ubuntu社区及其论坛
  14. 百度地图坐标系统解析
  15. python切片原理_彻底理解Python list切片原理
  16. 为什么称冯诺依曼为电子计算机之父,为什么说冯诺依曼是现代电子计算机之父...
  17. keycloak 添加 注册邮箱后缀验证
  18. 基督信仰与电脑软件 随笔
  19. qq音乐网络异常获取音乐失败_QQ音乐怎么诊断网络异常
  20. npack v1.1.300 beta by NEOx/[uinc]

热门文章

  1. oracle erp和金蝶,ERP和金蝶软件有什么区别!
  2. 连锁百货企业数据分析系统建设方案
  3. 那些在2009年失意的互联网“伟人”
  4. 2021Java笔试真题,满满干货指导
  5. echarts找到china地图( npm i --save echarts/map/js/China)
  6. 读书郎平板中android,读书郎学生平板电脑怎么用 使用方法详解【图文】
  7. EasyRecovery15电脑版数据恢复工具 国内免费的数据恢复软件
  8. 细数二三四五“爆雷”简史:布局金融7年一场空,陈于冰贯穿始终
  9. 嵌入式驱动那年的笔试面试-有干货
  10. 关于不同进位制之间的相互转化