作者 | 科技缪缪

来源 | 科技缪缪(ID:kejimiumiu)

头图 |  CSDN 下载自东方IC

秒杀这个话题到现在来说已经是一个老生常谈的话题了,不过因为又临近一年一度的双11,而且发现前段时间无论是阿里还是腾讯一些大厂其实还是在频繁的问到这个场景题,所以还是准备拿出来说说。

秒杀从规模上来说可以分为大秒和小秒。大秒指的是比如双11这种特定的节日,商品规模超大、价格超低、流量超大的这种类型活动,小秒一般指的是商家自己配置的一些时段类型的活动,由商家自己指定时间上架。从形式来说还可以分为单时段秒杀和多时段秒杀。但是在这个场景里,我们一般就是指的单时段大型秒杀。

秒杀设计要面对的压力和难度有几点:

  1. 怎么保证超高的流量和并发下系统的稳定性?如果峰值的QPS达到几十万,面对巨大的流量的压力系统怎么设计保证不被打崩?

  2. 怎么保证数据最终一致性?比如库存不能超卖,超卖了那亏本的要么就是商家要么就是平台,用户反正不背这个锅,超卖了就今年325预订。

当然,涉及到这种大型的活动,还需要考虑到数据统计分析,总不能活动做完了,效果不知道怎么样。

系统架构

假设今年的双11预估峰值QPS将会有50万(我随便扯的),而根据我们平时的经验单机8C8G的机器可以达到1000左右的QPS,那么从理论上来说我们只要500台机器就可以抗住了,就有钱任性不行?这么设计的话只能出门右转不送了。

一、流量过滤

本质上,参与秒杀的用户很多,但是商品的数量是有限的,真正能抢到的用户并不多,那么第一步就是要过滤掉大部分无效的流量。

  1. 活动开始前前端页面的Button置灰,防止活动未开始无效的点击产生流量

  2. 前端添加验证码或者答题,防止瞬间产生超高的流量,可以很好的起到错峰的效果,现在的验证码花样繁多,题库有的还要做个小学题,而且题库更新频繁,想暴力破解怕是很难。当然我知道的还有一种人工打码的方式,不过这个也是需要时间的,不像机器无限刷你的接口。

  3. 活动校验,既然是活动,那么活动的参与用户,参加条件,用户白名单之类的要首先做一层校验拦截,还有其他的比如用户终端、IP地址、参与活动次数、黑名单用户的校验。比如活动主要针对APP端的用户校验,那么根据参数其他端的用户将被拦截,针对IP、mac地址、设备ID和用户ID可以对用户参与活动的次数做校验,黑名单根据平时的活动经验拦截掉一部分羊毛党等异常用户。

  4. 非法请求拦截,做了以上拦截如果还有用户能绕过限制,那不得不说太牛X了。比如双11零点开始还做了答题限制,那么正常人怎么也需要1秒的时间来答题吧,就算单身30年手速我想也不能超过0.5秒了,那么针对刚好0点或者在0.5秒以内的请求就可以完全拦截掉。

  5. 限流,假设秒杀10000件商品,我们有10台服务器,单机的QPS在1000,那么理论上1秒就可以抢完,针对微服务就可以做限流配置,避免后续无效的流量打到数据库造成不必要的压力。针对限流还有另外一种栅栏方式限流,这是一种纯靠运气的限流方式,就是在系统约定的请求开始的时间内随机偏移一段时间,针对每个请求的偏移量不同,如果在偏移时间之内就会被拦截,反之通过。

二、性能优化

做完无效流量的过滤,那么可能你的无效请求已经过滤掉了90%,剩下的有效流量会大大的降低系统的压力。之后就是需要针对系统的性能做出优化了。

  1. 页面静态化,参与秒杀活动的商品一般都是已知的,可以针对活动页面做静态化处理,缓存到CDN。假设我们一个页面300K大小,1千万用户的流量是多少?这些请求要请求后端服务器、数据库,压力可想而知,缓存到CDN用户请求不经过服务器,大大减小了服务器的压力。

  2. 活动预热,针对活动的活动库存可以独立出来,不和普通的商品库存共享服务,活动库存活动开始前提前加载到redis,查询全部走缓存,最后扣减库存再视情况而定。

  3. 独立部署,资源充足的情况下可以考虑针对秒杀活动单独部署一套环境,这套环境中可以剥离一些可能无用的逻辑,比如不用考虑使用优惠券、红包、下单后赠送积分的一些场景,或者这些场景可以活动结束后异步的统一发放。这只是一个举例,实际上单独针对秒杀活动的话你肯定有很多无用的业务代码是可以剥离的,这样可以提高不少性能。

经过这两步之后,最终我们的流量应该是呈漏斗状。

超卖

秒杀除开高并发高流量下的服务稳定性之外,剩下的核心大概就是怎么保证库存不超卖了,也可以说要保证的是最终一致性。一般来说,针对下单和库存有两种方式:

  1. 下单即扣库存,这是最常规的大部分的做法。但是可能在活动中会碰到第二点说到的情况。

  2. 支付完成扣库存,这种设计我碰到过就是酒店行业,廉价房放出来之后被黄牛下单抢占库存导致正常用户无法下单,然后黄牛可以用稍高的价格再售卖给用户从中牟利,所以会有在一些活动的时候采取支付成功后才占用库存的做法。不过这种方式实现起来比较复杂,可能造成大量的无效订单,在秒杀的场景中不太适用。

针对秒杀建议选择下单扣库存的方式,实现相对简单而且是常规做法。

方案:

  1. 首先查询redis缓存库存是否充足

  2. 先扣库存再落订单数据,可以防止订单生成了没有库存的超卖问题

  3. 扣库存的时候先扣数据库库存,再扣减redis库存,保证在同一个事务里,无论两者哪一个发生了异常都会回滚。有一个问题是可能redis扣成功了由于网络问题返回失败,事务回滚,导致数据库和缓存不一致,这样实际少卖了,可以放到下轮秒杀去。

这种做法能一定程度上解决问题,但是也有可能会有其他问题。比如当大量请求落在同一条库存记录上去做update时,行锁导致大量的锁竞争会使得数据库的tps急剧下降,性能无法满足要求。

另外一种做法就是排队,在服务层进行排队,针对同一个商品ID的也就是数据库是一条库存记录的做一个内存队列,串行化去扣减库存,可以一定程度上缓解数据库的并发压力。

质量保障

为了保证系统的稳定性,防止你的系统被秒杀,一些质量监控就不得不做。

  1. 熔断限流降级,老生常谈,根据压测情况进行限流,可以使用sentinel或者hystrix。另外前端后端都该有降级开关。

  2. 监控,该上的都上,QPS监控、容器监控、CPU、缓存、IO监控等等。

  3. 演练,大型秒杀事前演练少不了,不能冒冒失失的就上了吧。

  4. 核对、预案,事后库存订单 金额、数量核对,是否发生超卖了?金额是否正常?都是必须的。预案可以在紧急情况下进行降级。

数据统计

活动做完了,数据该怎么统计?

  1. 前端埋点

  2. 数据大盘,通过后台服务的打点配合监控系统可以通过大盘直观的看到一些活动的监控和数据

  3. 离线数据分析,事后活动的数据可以同步到离线数仓做进一步的分析统计

总结

总的来说,面对巨量的流量我们的方式就是首先通过各种条件先筛选掉无效流量,进行流量错峰,然后再对现有的系统性能做出优化,比如页面静态化,库存商品预热,也可以通过独立部署的方式和其他的环境做隔离,最后还要解决高并发下缓存一致性、库存不能超卖的问题,防止大量的并发打爆你的数据库。

一个完整的活动从前端到后端是一个完整的链路,中间有事前的演练工作,事后的数据分析等都是必不可少的环节。

更多精彩推荐
☞谁说中国没有 Linus?中国初代 IT 宗师封神榜
☞程序员连续加班在餐厅泪崩,谁不是每逢上线必通宵!
☞打工人,今年双十一你刷啥?☞有了图分析,可解释的AI还远吗?☞一文教你如何在生产环境中在Kubernetes上部署Jaeger
☞数字政务是“新常态”——如何确保其合乎道德规范?
点分享点点赞点在看

双十一的秒杀场景是如何设计的?相关推荐

  1. 【JavaP6大纲】功能设计篇:秒杀场景设计

    秒杀场景设计 流量过滤: 本质上,参与秒杀的用户很多,但是商品的数量是有限的,真正能抢到的用户并不多,那么第一步就是要过滤掉大部分无效的流量. 活动开始前前端页面的Button置灰,防止活动未开始无效 ...

  2. 苏宁高时效、高并发秒杀业务中台的设计与实现

    设计背景 对于苏宁易购主站而言,正常的用户购物流程囊括选品.下单.库存扣减.付款.订单状态更新.物流履约等.但是在电商业务中往往会涉及到对某些热点商品的秒杀场景.相比于正常购物流程,秒杀场景具有时效性 ...

  3. 第一百三十五期:如何模拟一次阿里双11秒杀场景的实现?程序员必看

    秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购,我们生活的方方面面都可以看到秒杀的身影. 作者:IT技术管理那些事儿 秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购 ...

  4. 数据库并发抢红包_秒杀场景实践之抢红包

    前言 秒杀场景在生活中几乎随处可见, 不论是商品抢购.春运抢票还是一个随处可见的红包, 都会涉及到秒杀的场景. 在面试中, 秒杀业务的设计也成为热门题目为面试官和应聘者津津乐道. 接下来, 本文将针对 ...

  5. 秒杀场景的九个细节,细思极恐!

    往期热门文章:1.放弃MyBatis!我选择 JDBCTemplate! 2.生成订单30分钟未支付,则自动取消,该怎么实现? 3.Lombok代码"亚健康"元凶? 4.IDEA的 ...

  6. 秒杀场景下超卖问题解决方案

    秒杀超卖现象:在高并发下,多个线程并发更新库存,导致库存为负的情况. 我搜集了一些资料,整理了一下,秒杀可选方案主要有以下三种: 1.超卖原因 一个简单的订单表 create table orders ...

  7. 关于秒杀场景的全面分析总结

    1.技术层面 1.高访问压力隔离 将秒杀系统独立部署,甚至使用独立域名,使其与网站完全隔离. 2.用户在秒杀开始前,通过不停刷新浏览器页面以保证不会错过秒杀.但是持续刷新商品页面详情页会对服务器造成压 ...

  8. kafka mysql秒杀框架_一次模拟简单秒杀场景的实践 Docker Node.js Kafka Redis MySQL...

    秒杀活动可以说在互联网上随处可见,从12306抢票,到聚划算抢购,我们生活的方方面面都可以看到秒杀的身影.秒杀的架构设计也是对于一个架构师架构设计能力的一次考验.本文的目的并不在于提供一个可以直接落地 ...

  9. 06 秒杀系统“减库存”设计的核心逻辑

    如果要设计一套秒杀系统,那我想你的老板肯定会先对你说:千万不要超卖,这是大前提. 如果你第一次接触秒杀,那你可能还不太理解,库存100件就卖100件,在数据库里减到0就好了啊,这有什么麻烦的?是的,理 ...

最新文章

  1. i7 7700hq安装Linux,黑苹果安装火影金刚4K VULCAN JinGang GTX i7-7700HQ 独显驱动 Hackintosh...
  2. 选本还是从缓存设计理念选择更好
  3. 存根类 测试代码 java_常规单元测试和存根–测​​试技术4
  4. 防抖函数和节流函数的实现,这个是在某保险公司笔试题遇到的。
  5. 修改mysql数据引擎的方法- 提高数据库性能
  6. PDMS Pipeline Tool 教程(四):目录树顺序检查
  7. ASCII码不可见字符过滤处理
  8. 微信小程序头像怎么改变形状_如何实现微信小程序换头像?三步帮你搞定!
  9. 基于STM32的物联网环境监测系统
  10. php自我介绍50字,简短自我介绍50字
  11. [翻译]Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
  12. 程序猿生存指南-53 春日凉亭
  13. docker搭建mongodb高可用集群
  14. Latex系列2---段落编写+标题编写+目录生成
  15. C++ bitset的用法实例
  16. 前端开发工具HbuilderX的使用技巧
  17. android 8.0 屏蔽首次开机弹出的‘即将完成 Android 更新’的弹窗
  18. 前端技能汇总 知识结构
  19. java三层、四层和五层结构介绍
  20. vue项目让局域网ip访问配置设置

热门文章

  1. asp.net怎样在URL中使用中文、空格、特殊字符
  2. CRM【第三篇】: crm业务
  3. 学习mysql随笔——mysql的安装启动
  4. 【python-dict】dict的使用及实现原理
  5. 吴昊品游戏核心算法(新年特别篇)——另类取石子游戏(斐波那契博弈)
  6. Javascript是实现HTML5强大功能的重要语言
  7. C# 在 webBrowser 光标处插入 html代码 .
  8. [Git] 删除远程仓库的文件
  9. [C/C++] gdb 调试
  10. [论文阅读] Learning a Unified Classifier Incrementally via Rebalancing