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