秒杀系统怎么区分真实用户和黄牛脚本?

0 阅读2分钟

很多人以为加个验证码就行了。实际生产环境里,秒杀活动根本不会用验证码。用户体验差是一方面,更关键的是秒杀的时间窗口太短,多一步交互就多一层流失。

我在做6000万会员的秒杀系统时,用的是一套四层防刷体系。其中第二层叫机审校验,原理并不难,但设计上有几个值得说的点。

大致思路:用户打开活动页时,前端悄悄调一个预检接口,服务端生成一个随机串和时间戳,用时间戳决定在随机串的某个位置插入一个标记字符,结果存进Redis,30秒过期。前端拿到随机串和时间戳后,在本地用同样的算法算出校验值。用户点抢购时把这个值带回来,服务端比对,一致就放行,用完即删。

这个方案有三个讲究的地方:

  • 字段名刻意模糊。 返回给前端的字段不叫 randomString 和 timestamp,而是叫 result 和 key。前端代码在浏览器里能被审查,字段名越直白,脚本逆向的成本越低。
  • 只做一次Redis读。 机审放在整条链路的最前面,执行代价是一次Redis GET加一次字符串比对。它的定位不是对抗高级逆向,而是用最低的成本过滤掉最大比例的垃圾流量。那些直接构造HTTP请求、压根不走前端页面的批量工具,到这一步就全被挡住了。
  • 可以秒级关闭。 所有参数都通过Nacos配置中心管理,包括开关、随机串长度、令牌有效期。大促前如果发现误杀率偏高,运营在Nacos控制台点一下,机审就关了,不用重启服务。

有人会问:这算法被逆向了怎么办?不怕。防刷体系是分层递进的,机审只是第二层。后面还有用户级限流(Redisson RRateLimiter按单用户控速)、小黑屋(提前探路的用户自动标记)、消费端二次过滤。每一层解决一类问题,不指望某一层解决所有问题。

防刷不是一道墙,而是一张网。每一层筛掉一部分,叠在一起就是一个完整的过滤漏斗。

这是我正在写的秒杀专栏里的一个片段。整个专栏30篇,从需求PRD到应急预案,覆盖了一个6000万会员秒杀系统从零到上线的完整过程。每篇都有真实项目的代码和配置,不是画架构图讲概念,是拿过去改一改就能落地的那种。

如果你正在做秒杀相关的项目,或者想系统地补一下高并发场景的实战经验,可以看看。

专栏发布在知乎里,我的知乎账号:

  • SamDeepThinking