最便宜的过滤层
漏斗的第一层不在机房,在用户手机里:一次端上的拦截,省下的是一次完整的网络往返加后端调用——成本约等于零,收益是实打实的一次系统容量。很多人觉得前端只是"展示",但在秒杀架构里,端上是第一道闸门,拦得住的东西越多,后面每一层的压力越小。
静态化与 CDN:让页面自己扛自己
秒杀页的访问量可能是平时的百倍,但页面结构基本不变——把它静态化:HTML、图片、JS 全部推上 CDN,商品信息在开抢前预生成静态数据,页面加载几乎不回源。需要动态的只有两小块:开抢时间校准(客户端时间不可信,用服务端时间校准误差)和库存状态轮询(低频、轻量)。让 90% 的页面流量终结在 CDN 边缘节点,源站只需要服务真正的下单请求。
防抖与错峰:拦住冲动与连点
真人用户贡献的第一大头是连点:抢不到就狂点,一秒八次——每次都是一条要系统接住的请求。两个端上动作:点击后按钮立即置灰进入 loading 态,请求返回前禁止再点;请求带上节流,同一用户同一活动秒级窗口内只放行一次。错峰是更巧的一刀:开抢时间给每个用户加一个零点几秒的随机偏移,10 万人的"同一秒"被摊开成两三秒的缓坡,瞬时洪峰直接腰斩——用户毫无感知,系统压力减半。
// 端上削峰三件套
let firing = false;
async function seckill() {
if (firing) return; // 1. 防重入:请求未返回不可再点
firing = true;
const jitter = Math.random() * 800; // 2. 错峰:0~800ms 随机延迟
await sleep(jitter);
const r = await api.post("/seckill", { skuId, token: genToken() });
render(r); // 3. 结果置灰:售罄后按钮永久置灰
firing = false;
}答题与滑块:把洪峰拉成缓坡
想再压一压瞬时峰值,就给下单前加一道轻交互:答题、滑块、拼图。真人答题要花三到十秒——原本挤在同一秒的请求,被自然摊开成一条缓坡,答对才有下单资格,洪峰就这样被物理时间拉平。附带收益是对脚本的第一道筛选:脚本秒答题或者不答题,行为特征一目了然。注意题要"轻":三秒内能完成的简单题,否则真人也答不完,体验反噬。
动态 URL:别让脚本提前囤弹药
如果下单 URL 提前可预测,脚本会提前写好请求,开抢瞬间机器对机器,真人毫无胜算。解法是把秒杀地址做成动态的:开抢前页面里只有加密参数,真正的下单地址要先用身份信息换取一次性 token 才能拼出,token 短时效、单次有效、绑定用户与活动。脚本没法提前囤 URL,只能开抢后再请求页面解析——多了一跳,也多了一次被识别的机会。
端上拦得住君子,拦不住脚本——剩下的流量交给系统层。下一篇进入网关:限流、防刷与黑名单。
评论 (0)