秒杀系统如何识别黄牛脚本
秒杀系统最怕的其实不只是“流量大”。
正常用户再多,至少大家都是:
打开页面
↓
看商品
↓
点抢购
↓
提交订单
黄牛脚本就不一样了。
可能在秒杀开始的一瞬间:
100个账号
1000个请求
几十台代理机器
同时打进来。
如果系统只遵循:
谁请求先到,库存就给谁。
最后很可能出现一种很尴尬的结果:
服务器扛住了,商品却全被脚本抢走了。
所以真正的秒杀系统,除了抗高并发,还必须解决另一个问题:
这个请求到底像不像一个正常用户?
一、系统其实并不能真正知道“你是不是人”
这是理解秒杀风控最重要的一点。
服务端收到一个请求:
POST /seckill
它看到的只是一些数据:
userId
IP
Cookie
Token
设备信息
请求时间
行为记录
服务器并没有办法隔着网络看见:
“电脑前面坐的是张三,还是一段 Python 代码。”
所以真正的实现方式并不是:
真人 → 放行
机器人 → 拦截
而是:
收集行为特征
↓
计算风险
↓
低风险放行
中风险验证
高风险拦截
也就是说:
秒杀反黄牛,本质上是风险识别,而不是机器识别。
二、最简单的一层:请求频率
假设正常用户抢一个商品。
可能是:
10:00:00.123 点击抢购
10:00:01.350 网络重试一次
但某个账号出现:
10:00:00.001
10:00:00.006
10:00:00.011
10:00:00.016
10:00:00.021
5毫秒一个请求。
基本就不用研究他的鼠标轨迹了。
人类正常情况下很难做到这种频率。
因此第一层通常就是:
IP限流
+
账号限流
+
设备限流
例如:
同一账号
1秒最多3次
同一设备
1秒最多5次
超过直接拒绝。
但只靠 IP 不够。
因为黄牛完全可以准备:
代理IP A
代理IP B
代理IP C
代理IP D
...
所以真正的风控不会只盯着一个 IP。
三、为什么还需要“设备指纹”?
假设一个黄牛控制了100个账号。
表面上:
账号不同
IP不同
手机号不同
看起来像100个人。
但仔细一看:
浏览器版本相同
屏幕分辨率相同
字体环境相同
操作系统相同
设备参数高度一致
甚至大量账号都来自同一种运行环境。
这时候系统就可以尝试生成:
Device Fingerprint
设备指纹。
它不一定是一个真实硬件序列号,而是根据多种客户端特征组合出的设备标识。
于是原来看到的是:
账号A
账号B
账号C
账号D
进一步分析可能发现:
┌→账号A
设备X ──┼→账号B
├→账号C
└→账号D
这就开始可疑了。
所以风控经常不是问:
这个账号有没有问题?
而是问:
这些账号之间是不是存在异常关联?
四、真正厉害的是行为识别
脚本最容易暴露的地方其实不是“速度快”。
而是:
太标准了。
正常用户的行为通常有随机性。
比如:
进入页面
↓
停留2.3秒
↓
滑一下页面
↓
看商品
↓
点击抢购
另一个人可能是:
进入页面
↓
停留5秒
↓
点击规则
↓
返回
↓
抢购
人类行为天然有噪声。
脚本则容易变成:
请求页面
100ms
请求接口
100ms
请求下单
100ms
1000个账号都是:
100ms
100ms
100ms
这反而非常不自然。
所以风控系统可以统计:
页面停留时间
点击间隔
请求间隔
操作路径
失败重试频率
请求时间分布
然后判断:
这组行为到底像不像正常用户。
五、一个特别形象的例子
假设10点整开始抢茅台。
真实用户的请求时间可能是:
10:00:00.128
10:00:00.417
10:00:01.032
10:00:01.784
分布比较散。
某批异常账号却全部是:
账号A 10:00:00.001
账号B 10:00:00.001
账号C 10:00:00.002
账号D 10:00:00.001
账号E 10:00:00.002
如果有几百个账号都出现这种情况,就很值得怀疑。
因为它们很可能不是几百个人同时练成了“毫秒级手速”。
更可能是:
同一套程序在统一调度。
所以风控真正找的是:
异常的规律性。
六、账号本身也有“画像”
再往下一层,可以看账号历史。
比如正常用户:
注册半年
有浏览记录
有正常订单
有地址
偶尔参加活动
某个账号:
昨天注册
没有任何浏览记录
没有历史订单
今天第一次登录
秒杀前1分钟上线
10点整精准请求
抢完立即退出
风险显然完全不一样。
所以系统可以给账号建立一些特征:
账号年龄
历史订单数
登录频率
收货地址
支付信息
活动参与频率
退款率
设备更换频率
最后形成:
User Risk Score
比如:
正常老用户 +0
新注册账号 +10
频繁切换IP +20
多个账号同设备 +30
毫秒级高频请求 +40
假设:
Risk Score < 30
→ 正常放行
30 ~ 70
→ 增加验证
> 70
→ 拒绝秒杀
真实系统当然会复杂很多,但底层思想基本就是这样。
七、验证码为什么不能一上来就给所有人?
很多系统想到防机器人,第一反应就是:
上验证码。
例如:
滑块
图片验证码
短信验证
确实有用。
但秒杀系统有一个特殊问题:
正常用户本来就很多。
如果100万人全部先做验证码:
用户体验下降
+
验证码服务压力暴涨
+
正常用户抱怨
所以更合理的是:
低风险用户
→ 直接通过
可疑用户
→ 滑块验证
高风险用户
→ 更强验证或者直接拒绝
这叫:
分级风控。
不是所有人都接受同样的验证成本。
八、为什么秒杀接口不能直接暴露?
假设页面里永远写死:
POST /api/seckill/10001
那么脚本根本不用打开页面。
它可以直接:
定时到10:00
↓
狂刷接口
因此实际设计中经常会增加一个“资格获取”过程。
例如:
进入活动
↓
完成必要校验
↓
获取短期秒杀资格
↓
携带资格访问下单接口
资格可以有:
用户绑定
商品绑定
过期时间
签名
一次性状态
服务端再验证:
资格是否合法?
是不是这个用户的?
是不是这个商品的?
有没有过期?
有没有重复使用?
这并不能让脚本彻底消失。
但它能把:
知道接口地址
=
可以直接抢
变成:
必须经过前面的业务链路
↓
才能获得下单资格
攻击成本会高很多。
九、为什么一定要多层拦截?
因为任何单一规则都容易误伤或者被绕过去。
只限制 IP:
换代理
只限制账号:
准备大量账号
只看设备:
伪造设备环境
只用验证码:
可能被打码平台或自动化识别绕过
所以真正有效的系统一般是:
CDN / WAF
↓
IP和网络层风控
↓
账号限流
↓
设备指纹
↓
行为分析
↓
风险评分
↓
必要时验证码
↓
秒杀资格校验
↓
Redis库存
↓
MQ
↓
创建订单
黄牛每突破一层,都要付出新的成本。
反黄牛真正追求的也不是:
世界上任何脚本都进不来。
这个目标基本不现实。
更实际的是:
让批量作弊的成本高到没有收益。
十、风控为什么不能写死成一堆 if?
最简单的系统可能这样写:
if (requestCount > 10) {
reject();
}
if (accountAge < 1) {
reject();
}
if (deviceUserCount > 5) {
reject();
}
刚开始能用。
规则越来越多以后,很快就会变成:
几十个if
+
规则互相冲突
+
误杀越来越严重
所以成熟一点的做法通常会抽象成:
特征
↓
风险规则 / 风控模型
↓
Risk Score
↓
决策
例如:
risk =
请求频率 × 权重
+ 设备异常 × 权重
+ 账号异常 × 权重
+ 行为异常 × 权重
然后根据风险等级采取不同措施。
这样以后发现新的黄牛模式,只需要增加:
新的特征
或者
新的规则
不需要把整个秒杀业务重写一遍。
总结
秒杀系统想区分真实用户和黄牛脚本,底层并没有一个神奇的:
isHuman()
真正做的是不断收集信号:
这个账号正常吗?
这个设备正常吗?
请求频率正常吗?
行为路径正常吗?
这些账号有没有关联?
请求时间是不是过于规律?
然后:
多维特征
↓
风险评分
↓
分级处理
所以反黄牛最核心的思想不是:
识别出所有机器人。
而是:
识别“正常人很少会出现,但批量自动化工具经常出现”的行为模式。
最后再通过:
限流 + 设备 + 账号 + 行为 + 验证 + 秒杀资格
层层提高作弊成本。
这也是秒杀风控最重要的底层逻辑:
真正有效的反黄牛,不是筑一道绝对攻不破的墙,而是让批量作弊变得越来越贵。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐



所有评论(0)