秒杀系统设计中的业务性思考
Posted 架构栈
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了秒杀系统设计中的业务性思考相关的知识,希望对你有一定的参考价值。
秒杀不是一个新鲜事物,特别是过去几年电商和互金业务的蓬勃发展,各种电商节的兴起,促使秒杀已经变成了非常重要的业务功能。我这几年也没少和“秒杀”打交道,和团队共同经历了各种挣扎后,积累了一些想法,今天想利用这个机会来写一写。但今天不是来教大家如何做一个秒杀系统的,而是从业务的角度来思考秒杀系统设计中,我们需要注意的地方。
业务对于秒杀的期望
既然我们要从业务的思路上来思考秒杀,那么我们就需要明确和转化,在秒杀场景下,我们期待的结果是什么。抛开具体业务,我简单总结了一下,可以分为以下两点:
1)每个用户都能参与,但是有且参与一次。
2)参与的用户都是真实有效的。
针对这两个业务需求,我再来分析一下,要满足这两个业务需求,我们的秒杀系统需要具备什么能力。
先说第1点,用技术的语言来翻译就是:同一个账户,无论通过浏览器插件或者其他任何辅助工具发出多次请求,他最多只能抢到一次。讲到这里,我必须要多说两句,这看似是一个简单的判断领取逻辑,但是不少团队在这里是犯过错误的,导致判断逻辑被绕过,没有达到去重的效果,如下图:
先判断用户A是否有参与记录,如果没有则领取成功,最后将用户A更新为已参与记录中。如果大家仔细想一下,就会发现这里藏着一个极大的漏洞:在高并发的场景下,在某个请求成功写入参与记录的时间段内,用户A其他的请求获查询到的结果都是“没有参与记录”。所以,就存在逻辑判断被绕过,同一个用户秒杀成功多次的情况出现。
正确的做法:
秒杀系统只允许接受同一个账户的1个请求,其他请求统统过滤掉。在程序入口加锁,同一个账户,同一时刻只有一个线程在被处理。不仅解决了同一个账号,发送多个请求的问题,还保证了后续的逻辑流程的安全,确保了只有一个线程能更新账户的状态。
第1个问题解决后,接下来,我们需要谈一下,怎么保证秒杀过程中,用户的真实性和有效性。
要总结出真实用户的行为是比较难的,但是要总结出非真实用户的行为相对容易,所以我们采用反证法的思路,将问题2进行一个拆解,列举出非真实用户行为的表现有哪一些:
IP相对固定(相近IP或者同一IP段),请求的频率超过正常人的反应速度
请求的路径缺乏逻辑,不能形成正常的业务链路。
User-Agent异常,URL携带的参数存在明显的拼接痕迹。
针对以上几点非正常情况,我们可以有以下两种防范措施:
1. 对请求频率过快的IP进行限制。 可以在nginx或者Tengine上执行,详细信息,可以参见之前我有关。
2. 频率请求过快或者请求头异常的请求,返回图形验证码到前端(建议不要使用简单的数字验证码),触发人工解锁,确保背后是真实的人存在。
进一步思考
实际上,光靠这些技术手段还是不够的,因为羊毛党或者黄牛党是在不断进化手段的,人家也肯下血本。所以我们真要做好秒杀,还需要更多从业务上思考。我在这里也总结了2点,可以尝试:
分析用户画像,根据用户的活跃度,等级,资料的齐全程度,历史购买产品,对用户进行评分,达到特定分数的用户才能参与秒杀。
制定业务门槛,比如说,要参与秒杀,对于一个电商平台,该用户过去至少有1000元的历史消费额,对于一个理财平台,该用户必须要有订单在投,等等。
有了这2点,可以说基本上保证了用户的真实性,或者说让造假的动机没了,保证99%以上的黄牛号或者僵尸号能被过滤掉。
选择“秒杀券”还是“秒杀商品”
最后,再想讨论一个话题,如果要做一个秒杀系统,是先从秒杀券做起,还是从秒杀商品开始做起呢?个人建议先通过秒杀券练练手,然后再转向秒杀商品。原因很简单,因为秒杀商品,一下就引入了订单和支付,库存的锁定和释放,支付的时效等等,涉及到的业务复杂度就高了一个层次。从另外一个角度看,秒杀券是和正常的业务流程隔离的,是不会影响到正常的下单流程的。即便是出问题了,做服务降级也会容易许多。
预告一下:明天会讲一下商品秒杀系统的落地方案,欢迎围观。
欢迎转载,带上以下二维码即可
点击“阅读原文”,所有【架构栈】近期的架构文章汇总
↓↓↓
以上是关于秒杀系统设计中的业务性思考的主要内容,如果未能解决你的问题,请参考以下文章