引言:
2020年是一个疫情年,口罩、酒精等防护用品,鸡蛋、肉等生活物资,统统限量销售,“秒杀”成了新一年的代名词。
But,秒杀成功不仅只靠运气哒 ~
下面从技术的角度来分析,影响秒杀的三个因素:
➤ 前端逻辑:前端设计秒杀三个状态(未开始,秒杀中,已结束)。
➤ 后端约束:产品特殊需求,风控策略及接口设计的影响。
➤ 网速的快慢:同一秒杀活动,同一界面前提下直接影响秒杀速度。
先来一张秒杀流程图:
◉ 首先,我们来看下秒杀活动设计阶段的前端逻辑:
进入页面要先调用一个接口,接口中返回三个时间戳和页面的基础信息,然后拿到信息前端开始渲染页面,我们就能看见秒杀界面了,为了达到真实的倒计时的界面效果,前端会设计一个定时器,定时刷新倒计时。
通过调用服务端接口返回三个时间戳计算出来当前状态,并且在当前状态倒计时为 00:00:00 时,自动刷新数据,拿到新的状态值,从而主动完成状态切换,即秒杀开始或结束。
那么前端的那些设计会影响到秒杀进程呢?
1、定时器执行时间的设定。
由于倒计时最直观的展现给用户,而定时器的执行时间又直接影响倒计时,如何让倒计时更加精准?建议将执行时间设置为 17ms - 1000ms 之间,并且无线趋近于17越准确,这个结论是怎么得出的呢?接着往下看。
由于界面倒计时通常为 (天:)时:分:秒,因此前端逻辑中,最高以 1秒(1000ms) 进行递减,setInterval定时器时间:
// STime 为开始时间戳,CTime 为当前时间戳,ETime 为结束时间
let leftTime = STime - CTime
const step = 1000
setInterval(()=>{
leftTime = leftTime - step
}, step)但是如果这个时候:
let leftTime = STime - CTime =`1000 * 10 + 800 ms倒计时超过了10秒,又不足11秒,我们当前界面展示为 00:00:10 ,最后一秒后,其实还有真是的剩余时间 800ms,那么就会出现 00:00:00 还不能秒杀的情况,这个时候可能会被用户投诉;为了避免这个问题,我们采取`进1法`,不足1秒加一秒,界面展示 00:00:11,这种情况下等到最后一秒,也就是过了 1000 * 11 秒,又明显的滞后了(这里接口请求时间忽略不计)。
因此,我们需要减少定时器的执行时间,极限值17ms,那么这个时间是怎么来的?这个跟屏幕刷新率有关系,目前手机屏幕的刷新率普遍维持在60HZ,刷新率和帧率必须要同步显示,一旦两者出现差别,那么后一帧和前一帧画面会在同一时间交替出现,就会出现画面撕裂等显示异常。因此我们刷新频率为:10000/60 ≈ 17 。
所以当定时器执行时间无限趋近于17 会越准确。但是setInterval 的执行也在消耗内存,所以,大家根据实际情况具体设定吧!
2、避免按钮重复点击
2、避免按钮重复点击
有时候秒杀不必疯狂点击,好多做了无用功!
一般抢购按钮点击会发送请求进行下单操作,这个时候为了避免多次重复请求,一般会在前端进行拦截:发送请求直到数据返回结果或预定一个间隔时间,期间不允许再发送第二次接口,因为用户多次重复点击只取第一次。
◉ 接着,我们简单枚举下后端约束条件:
- 产品需求:产品根据用户画像来配置秒杀中单比例,比如:女性VS男性 秒杀成功率为 70% vs 30%,侧重推广投放女性用户。
- 风控策略:用户被该平台封禁或由于某些购买行为恶劣等,被列入黑名单,请求被拒绝永远不会秒杀中单成功。
- 接口设计:请求拦截,分段放行等,(这里有一些运气成分在) 刚好遇见一篇介绍秒杀系统的好文章 mp.weixin.qq.com/s/i6POWxca-…,感兴趣的同学可以了解下。
◉ 当然,在同一秒杀活动中,不管是前端逻辑还是后端约束条件都是一致的情况下,秒杀是在拼网速。
秒杀与网速的关系,核心在于 `CTime` 的准确性,当CTime 的误差足够小,倒计时越准确,秒杀成功率越高。
这是一个接口请求的Timing分布图,由此图整个耗时约70ms,其中
TTFB(Time To First Byte) 耗时为53ms, 53/2 ≈ 25ms
举个例子🌰:
举个例子🌰:
当前服务器时间为 CTime=100ms,开始时间STime =150ms,剩余时间 leftTime= 50ms (这里先不考虑渲染时间等其他因素)
◉ 如何提高秒杀成功率,设计一个秒杀器。
方案一:直接请求接口。
原理:直接请求接口,只消耗接口时间,减少页面渲染时间,快速下单。
方案二:预先抓取秒杀模板。
原理:直接跳过商品详情页,直接到下单页,替换即将下单的商品,进行下单。
方案三:代码批量提交。
原理:抓取商品详情页接口中获取特殊参数`value`,并透传这个参数到下单接口,通过校验,发送请求,秒杀成功。
秒杀安全性:
1、在下单接口中,加入一个特殊参数`key`,参数值`value`每次随机生成,下单接口校验拦截。
2、请求拦截,分段放行,负载均衡,减少并发。
3、产品策略加持,userID 限流,避免重复下单。
扩展阅读链接:
结束语:
人生与“秒杀”成功一样, 三分靠运气,七分靠打拼!
这是一篇酝酿了很久的笔记,希望对你能有所帮助,抛转引玉,大家有什么想法 ~ 来 ~ 👇集思广益 ~
「 祝: 所有的女孩们仙女节快乐! 中国早日战胜疫情 🇨🇳加油! 来自零点的问候 ღ( ´・ᴗ・` ) . 」
「 祝: 所有的女孩们仙女节快乐! 中国早日战胜疫情 🇨🇳加油! 来自零点的问候 ღ( ´・ᴗ・` ) . 」