秒杀系统架构分析与实战( 七 )


这种账号,使用在秒杀和抢购里,也是同一个道理 。例如,iphone官网的抢购,火车票黄牛党 。

秒杀系统架构分析与实战

文章插图
应对方案:
这种场景,可以通过检测指定机器IP请求频率就可以解决,如果发现某个IP请求频率很高,可以给它弹出一个验证码或者直接禁止它的请求:
  1. 弹出验证码,最核心的追求,就是分辨出真实用户 。因此,大家可能经常发现,网站弹出的验证码,有些是“鬼神乱舞”的样子,有时让我们根本无法看清 。他们这样做的原因,其实也是为了让验证码的图片不被轻易识别,因为强大的“自动脚本”可以通过图片识别里面的字符,然后让脚本自动填写验证码 。实际上,有一些非常创新的验证码,效果会比较好,例如给你一个简单问题让你回答,或者让你完成某些简单操作(例如百度贴吧的验证码) 。
  2. 直接禁止IP,实际上是有些粗暴的,因为有些真实用户的网络场景恰好是同一出口IP的,可能会有“误伤“ 。但是这一个做法简单高效,根据实际场景使用可以获得很好的效果 。
##6.3 多个账号,不同IP发送不同请求## 所谓道高一尺,魔高一丈 。有进攻,就会有防守,永不休止 。这些“工作室”,发现你对单机IP请求频率有控制之后,他们也针对这种场景,想出了他们的“新进攻方案”,就是不断改变IP 。
秒杀系统架构分析与实战

文章插图
有同学会好奇,这些随机IP服务怎么来的 。有一些是某些机构自己占据一批独立IP,然后做成一个随机代理IP的服务,有偿提供给这些“工作室”使用 。还有一些更为黑暗一点的,就是通过木马黑掉普通用户的电脑,这个木马也不破坏用户电脑的正常运作,只做一件事情,就是转发IP包,普通用户的电脑被变成了IP代理出口 。通过这种做法,黑客就拿到了大量的独立IP,然后搭建为随机IP服务,就是为了挣钱 。
应对方案:
说实话,这种场景下的请求,和真实用户的行为,已经基本相同了,想做分辨很困难 。再做进一步的限制很容易“误伤“真实用户,这个时候,通常只能通过设置业务门槛高来限制这种请求了,或者通过账号行为的”数据挖掘“来提前清理掉它们 。
僵尸账号也还是有一些共同特征的,例如账号很可能属于同一个号码段甚至是连号的,活跃度不高,等级低,资料不全等等 。根据这些特点,适当设置参与门槛,例如限制参与秒杀的账号等级 。通过这些业务手段,也是可以过滤掉一些僵尸号 。
#7 高并发下的数据安全# 我们知道在多线程写入同一个文件的时候,会存现“线程安全”的问题(多个线程同时运行同一段代码,如果每次运行结果和单线程运行的结果是一样的,结果和预期相同,就是线程安全的) 。如果是MySQL数据库,可以使用它自带的锁机制很好的解决问题,但是,在大规模并发的场景中,是不推荐使用MySQL的 。秒杀和抢购的场景中,还有另外一个问题,就是“超发”,如果在这方面控制不慎,会产生发送过多的情况 。我们也曾经听说过,某些电商搞抢购活动,买家成功拍下后,商家却不承认订单有效,拒绝发货 。这里的问题,也许并不一定是商家奸诈,而是系统技术层面存在超发风险导致的 。
##7.1 超发的原因## 假设某个抢购场景中,我们一共只有100个商品,在最后一刻,我们已经消耗了99个商品,仅剩最后一个 。这个时候,系统发来多个并发请求,这批请求读取到的商品余量都是99个,然后都通过了这一个余量判断,最终导致超发 。
秒杀系统架构分析与实战

文章插图
在上面的这个图中,就导致了并发用户B也“抢购成功”,多让一个人获得了商品 。这种场景,在高并发的情况下非常容易出现 。
##7.2 悲观锁思路## 解决线程安全的思路很多,可以从“悲观锁”的方向开始讨论 。
悲观锁,也就是在修改数据的时候,采用锁定状态,排斥外部请求的修改 。遇到加锁的状态,就必须等待 。
秒杀系统架构分析与实战

文章插图
虽然上述的方案的确解决了线程安全的问题,但是,别忘记,我们的场景是“高并发” 。也就是说,会很多这样的修改请求,每个请求都需要等待“锁”,某些线程可能永远都没有机会抢到这个“锁”,这种请求就会死在那里 。同时,这种请求会很多,瞬间增大系统的平均响应时间,结果是可用连接数被耗尽,系统陷入异常 。


推荐阅读