前端秒杀/抢购系统防刷与高可用策略

场景题: “为了给公司的周年庆引流,下周二我们要上线一个极其残暴的:‘10万台 iPhone 9 块 9 秒杀活动!’ 活动倒计时一结束,全国几百万用户的疯狂点击、甚至黄牛们用 Python 脚本挂载的海量轰炸,会在 1 秒内铺天盖地冲垮后端所有的机器和数据库大楼。 作为大前端架构组的核心成员,你要在从用户浏览器到网关后端这全链路的路上,筑起哪几道铜墙铁壁或者泄洪闸,帮后端挡住那如丧尸般的并发怒潮?

这是一个极致考察前端工程师对后端性能之“怜悯”,以及在极限并发场景下的降级分流架构能力的压轴题。

我们的防守原则就八个字:“削峰填谷,分级拦截!

防线一:前端纯物理按钮防刷与冷却(漏斗口第一道墙)

别小瞧这一层,你拦下的绝不是正常人,而是那些疯狂抽搐手指的非理性小白! 一旦从后端拉取到系统精确服务器倒计时(避免本地被改时间作弊)且结束倒计时进入 00:00:00。 按钮必须:

  1. 立即进入 Loading 残疾状态(或禁用):点第一下后,不管请求有没出去,立刻禁用按钮!让用户在抢购结果(哪怕是排队页面)返回前,物理上丧失重重点第二下的操作杠杆。
  2. 极短的防抖 (Debounce) 或节流 (Throttle):利用之前的组件基建强行卡死快速多点。如果业务上允许狂点,给个 300ms 冷却,把每人狂点 5 次聚变吸收为仅 1 次出网。(关于防抖的细致讨论参考 防抖与节流)。

防线二:答题/花式验证码防“黄牛脚本与外挂大军”!

如果防线一是防真人的肉体狂欢。防线二就是利用“人的不可被外挂取代特征”掐死几十万乃至上百万的并发爬虫发包机器代码潮!

核心战术(逼你在狂风骤雨时做题!): 黄牛一般不是用浏览器抢。他们用 Nodejs / Python 发 POST,你的 JS 防抖对他们而言如同废纸。 当那神圣的倒数秒数 0 到来的那一瞬: 别急着放请求!前端强制立刻闪崩弹出一个极其抽象极难的外星人答题验证码/滑动拼图验证码。(这并不是刁难,这是电商大厂最赖皮拖延且高效保命的手段)。

  • 只有真正用手解题并通过计算的人,才会拿到验证码系统下发的“二次票据签名 (Token B)”。
  • 人手解题会有极大的时间方差(有人眼疾手快 1s 滑到,有人滑错重来 3s 才过),这把原本集中在 0 秒爆炸的几百万并发洪峰,奇迹般地像一条平缓拉长泄洪坡一样打散到了整整 3~5 秒内的稀疏长尾里!

防线三:带“血之封印”的下单动态隐秘 URL

即使过了验证码这一层,如果你前端写死调用的请求参数是这样的:POST /api/seckill/buy?goodsId=iPhone 有极大的隐患。 因为真正顶尖的黄牛黑客可以在活动还没开的几个小时前,就猜到了你的接口路径,强行把倒计时逻辑干掉,然后写脚本对着你的接口地址进行永不止息地狂轰滥炸。

防守利刃:极具隐秘色彩的动态加密接口(Path / Sign 随机化)

  • 不要在 HTML 或者 JS 里暴露你秒杀下单的真实 URL 或者商品核心 ID 参数!
  • 用户在通过答完刚刚防线二的问题后获得二次票据令牌的那个接口那一刹那,后端才根据极度保密甚至连时间戳都在跳舞的随机哈希算法生成一个专属个人的真·下单 URL(或者加密大参数 Secret Payload),利用那根仅有几毫米宽的安全线发还给你前端。如:/api/seckill/buy/9q8a7s6d5f4g3h2j1k
  • 你前端拿着这枚真正的“随机刺客”请求发往核心网关,后端才会认你。提前在浏览器中挂出猜接口的黑客们全军覆没,因为那些 URL 根本无从被预测到其行踪。

防线四:动静分离与 CDN 的狂欢顶配抗压 (性能与带宽)

大促当前,几百万人刷刷刷 F5 把商品详情页挤爆。如果页面上几十 M 的明星海报,华丽的动画资源都要经过你的秒杀商品服务器传输流来提供,后端的带宽没等商品倒计时开抢就直接活活拉起爆机。

架构基础:

  1. 静态资源全部上 CDN (内容分发网络):像图片、CSS、打包后的 JS(纯天然 SPA)这些千年不动的骨灰直接甩给全球分布式 CDN 节点。(让边缘机房去承担几百万人的重复提取暴风雨)。你的核心主数据机房一点带宽都不废。
  2. 极短时间本地缓存:配置 Cache-Control 和 ETag 甚至用 Service Worker,强行告诉用户机器:这个商品详情页面 1 分钟内的重新访问我都硬让你用这机器自己本地缓存里的!不要再发来服务器打扰。

终级升华与降级之道

如果是架构面试,在说尽了这些花哨的战术后。真正老成且值得将薪水挂到最高档次的护城河技术视野是什么? 是对最终防线失败失守时的柔性降级和用户兜底体验预案方案:

你可以自信地回答: “所有的高墙与重锁如果最后都在超乎想象的并发中被一一冲垮了,我的页面决不允许直接展示出冷冰冰恶心的由 Nginx 报出来的超大号字体的 502 Bad Gateway! 当后端被打爆超时了或者前端轮询由于错误不断捕获了失败时。 我会在全局设置一个极其丝滑的**全屏体验降级挡板(兜底 UI)**页面:它画着极其可爱呆萌的动画‘哎呀,人太多啦服务器挤爆了被挤走了,请重试’,或者是返回随机在前端生成的安慰奖。去利用极具情商且设计精细的友好反馈文案,最大程度平息并安慰因系统底层彻底雪崩导致根本点不进去的用户群体心中的怨恨情绪落差与焦躁感。这才是前端工程师最伟大最终极的不可替代的作用体验修罗场。”