2026年8月1日
秒杀系统 01 入口层防护与流量整理
第一阶段——入口层防护与流量整形
在请求真正打到核心业务逻辑(库存扣减)之前,尽可能把无效流量、恶意流量、瞬时峰值削掉。
一、秒杀页面静态化 + 动静分离
为什么要做这个: 秒杀开始前,商品详情、价格、图片这些"静态"信息如果每次都要请求后端渲染,会白白消耗服务器资源。而这些信息在活动期间根本不会变。
具体怎么做:
- 秒杀页面(HTML/CSS/JS/图片)提前生成好静态文件,推送到CDN
- 用户打开秒杀页面时,资源直接从CDN边缘节点拿,根本不经过你的服务器
- Nginx层面做规则区分:静态资源请求(图片、CSS、JS)直接走CDN或者Nginx本地缓存;只有"提交秒杀"这个动态请求(POST下单)才会真正打到后端服务集群
效果: 假设100万用户打开页面,如果没有动静分离,100万次页面渲染请求就会先把服务器打死,秒杀还没开始服务就先挂了。做了之后,这100万次请求大部分被CDN和Nginx缓存挡掉,真正打到后端的可能只有几万次"提交订单"请求。
二、秒杀链接加密
要解决的问题:
如果秒杀的下单接口地址是固定的、可预测的(比如 /seckill/1001/buy),黄牛可以写脚本在秒杀开始前就准备好,一开始就用脚本以极高频率(比如1000次/秒)攻击这个接口,普通用户手动点击根本抢不过脚本。
具体做法:
- 用户打开秒杀页面时,后端动态生成一个带时效性和签名的秒杀URL,比如:
/seckill/{商品ID}/{用户ID}/{时间戳}/{md5签名}/buy - 这个链接只有在页面渲染时才生成,并且设置很短的有效期(比如5分钟),过期作废
- 后端接收到请求后先校验签名和时效性,不合法的直接拒绝,根本不进入后续逻辑
- 这样黄牛就没法提前把接口地址写死在脚本里,必须先正常请求页面拿到链接,增加了攻击成本和门槛
进一步加强:
- 链接里的签名可以加上用户身份信息(比如登录token的一部分),防止链接被转发给别人使用
- 服务端可以对同一个链接设置"只能使用一次"(Redis SETNX打标记),用过就失效
三、验证码 + 流量错峰
核心思路: 既然瞬时并发是最大的敌人,那就想办法把同一时刻涌入的请求,在时间维度上"摊薄",而不是让它们全部集中在同一毫秒。
具体手段:
-
图形验证码/滑块验证码:用户点击"抢购"后先弹出验证码,这一步本身会消耗用户几秒的操作时间,天然把同一秒的请求分散到几秒钟的区间里。同时也能过滤掉一部分机器脚本(虽然打码平台可以破解,但增加了成本)
-
随机延迟下单按钮:很多秒杀系统会给"提交订单"这个动作加一个前端随机延迟(比如0~3秒内随机),用户看到的是"抢购中..."的loading动画,实际请求被错峰发出
-
"先加入购物车"策略:淘宝这类平台常用的手法——秒杀开始时不是直接让你下单,而是让你先把商品"加入购物车"(这个操作对库存没有实际影响,只是一个占位动作),然后系统统一在后面的时间窗口里处理购物车到订单的转化,进一步把瞬时冲击拉长
-
分批放量:比如10万件库存不是一次性开放,而是分成10批,每隔30秒放出1万件,人为把一次大流量拆成多次小流量
这一步的本质: 不是要减少总请求量,而是把"1秒内100万请求"变成"10秒内每秒10万请求",大幅降低瞬时峰值对系统的冲击。
四、恶意请求拦截
这一层跟"链接加密"是配合的,但拦截的维度更广,主要在**网关层(Nginx/API Gateway)**完成:
具体识别和拦截手段:
- IP维度限流:同一个IP在1秒内的请求次数超过阈值(比如超过5次),直接拉黑或者返回429
- User-Agent / 请求头异常识别:正常浏览器请求会带完整的请求头信息,脚本请求往往请求头残缺或者高度一致(同一个脚本发出的请求UA完全一样),可以用规则或者简单的机器学习模型识别
- 请求频率的行为模式分析:正常用户点击间隔有随机性(人手速有极限,不可能每次间隔都是精确的100ms),脚本请求的时间间隔往往异常规律,可以用这个特征做甄别
- 设备指纹/浏览器指纹:通过采集浏览器的canvas指纹、字体列表等信息生成设备唯一标识,同一设备短时间大量请求可以被识别并限制
- 黑名单机制:一旦识别出某个用户/IP/设备是刷单行为,加入黑名单,后续所有请求直接在网关层拒绝,不再消耗后端资源
这一层要注意的权衡: 拦截规则太严格容易误伤真实用户(比如公司/学校NAT出口共用一个IP,会被IP限流误伤),所以实际项目里往往是"IP限流 + 用户账号维度限流 + 设备指纹"多个维度组合判断,而不是单一依赖某一种手段。
这一部分的整体逻辑串起来看
用户打开秒杀页
→ CDN返回静态页面(动静分离,不打后端)
→ 页面渲染时生成带签名的动态链接(防止链接被预先破解/复用)
→ 用户点击抢购,前端做随机延迟/验证码(流量错峰)
→ 请求到达网关,IP/设备/行为维度做恶意请求识别拦截
→ 剩下的"干净"流量,才进入下一阶段的限流熔断和真正的业务处理
这一整套下来,理论上能把100万的原始流量,过滤削减到后端系统真正能扛住的量级(比如几万甚至几千QPS),这样后面的"限流熔断降级"和"库存扣减",压力就小很多了。