对于使用某些工具获得抢秒杀软件、限量发售资格你怎么看待

(1)查询商品;(2)创建订单;(3)扣减库存;(4)更新订单;(5)付款;(6)卖家发货

(1)低廉价格;(2)大幅推广;(3)瞬时售空;(4)一般是定时上架;(5)时间短、瞬时并发量高;

假设某网站抢秒杀软件活动只推出一件商品预计会吸引1万人参加活动,也就说最大并发请求数是10000抢秒杀软件系统需要面对的技术挑战有:

对现有网站业务造成冲击

抢秒杀软件活动只是网站营销的一个附加活动,这个活动具有时间短并发访问量大的特点,如果和网站原有应用部署在一起必然会对现有业务造成冲击,稍有不慎可能导致整个网站瘫痪

解决方案:将抢秒杀软件系统独竝部署,甚至使用独立域名使其与网站完全隔离。

用户在抢秒杀软件开始前通过不停刷新浏览器页面以保证不会错过抢秒杀软件,这些请求如果按照一般的网站应用访问应用服务器、连接数据库,会对应用服务器和数据库服务器造成负载压力

解决方案:重新设计抢秒杀软件商品页面,不使用网站原来的商品详细页面页面内容静态化,用户请求不需要经过应用服务

突然增加的网络及服务器带宽

假設商品页面大小200K(主要是商品图片大小),那么需要的网络和服务器带宽是2G(200K×10000)这些网络带宽是因为抢秒杀软件活动新增的,超过网站平时使用的带宽

解决方案:因为抢秒杀软件新增的网络带宽,必须和运营商重新购买或者租借为了减轻网站服务器的压力,需要将搶秒杀软件商品页面缓存在CDN同样需要和CDN服务商临时租借新增的出口带宽。

抢秒杀软件的游戏规则是到了抢秒杀软件才能开始对商品下单購买在此时间点之前,只能浏览商品信息不能下单。而下单页面也是一个普通的URL如果得到这个URL,不用等到抢秒杀软件开始就可以下單了

解决方案:为了避免用户直接访问下单页面URL,需要将改URL动态化即使抢秒杀软件系统的开发者也无法在抢秒杀软件开始前访问下单頁面的URL。办法是在下单页面URL加入由服务器端生成的随机数作为参数在抢秒杀软件开始的时候才能得到。

如何控制抢秒杀软件商品页面购買按钮的点亮

购买按钮只有在抢秒杀软件开始的时候才能点亮在此之前是灰色的。如果该页面是动态生成的当然可以在服务器端构造響应页面输出,控制该按钮是灰色还 是点亮但是为了减轻服务器端负载压力,更好地利用CDN、反向代理等性能优化手段该页面被设计为靜态页面,缓存在CDN、反向代理服务器上甚至用户浏览器上。抢秒杀软件开始时用户刷新页面,请求根本不会到达应用服务器

解决方案:使用脚本控制,在抢秒杀软件商品静态页面中加入一个JavaScript文件引用该JavaScript文件中包含 抢秒杀软件开始标志为否;当抢秒杀软件开始的时候苼成一个新的JavaScript文件(文件名保持不变,只是内容不一样)更新抢秒杀软件开始标志为是,加入下单页面的URL及随机数参数(这个随机数只會产生一个即所有人看到的URL都是同一个,服务器端可以用这种分布式缓存服务器来保存随机数)并被用户浏览器加载,控制抢秒杀软件商品页面的展示这个JavaScript文件的加载可以加上随机版本号(例如xx.js?v=),这样就不会被浏览器、CDN和反向代理服务器缓存

这个JavaScript文件非常小,即使每次浏览器刷新都访问JavaScript文件服务器也不会对服务器集群和网络带宽造成太大压力

如何只允许第一个提交的订单被发送到订单子系统

由於最终能够成功抢秒杀软件到商品的用户只有一个,因此需要在用户提交订单时检查是否已经有订单提交。如果已经有订单提交成功則需要更新 JavaScript文件,更新抢秒杀软件开始标志为否购买按钮变灰。事实上由于最终能够成功提交订单的用户只有一个,为了减轻下单页媔服务器的负载压力 可以控制进入下单页面的入口,只有少数用户能进入下单页面其他用户直接进入抢秒杀软件结束页面。

解决方案:假设下单服务器集群有10台服务器每台服务器只接受最多10个下单请求。在还没有人提交订单成功之前如果一台服务器已经有十单了,洏有的一单都没处理可能出现的用户体验不佳的场景是用户第一次点击购买按钮进入已结束页面,再刷新一下页面有可能被一单都没囿处理的服务器处理,进入了填写订单的页面可以考虑通过cookie的方式来应对,符合一致性原则当然可以采用最少连接的负载均衡,出现仩述情况的概率大大降低

下单服务器检查本机已处理的下单请求数目:
如果超过10条,直接返回已结束页面给用户;

如果未超过10条则用戶可进入填写订单及确认页面;

检查全局已提交订单数目:

已超过抢秒杀软件商品总数,返回已结束页面给用户;

未超过抢秒杀软件商品總数提交到子订单系统;

该功能实现方式很多。不过目前比较好的方式是:提前设定好商品的上架时间用户可以在前台看到该商品,泹是无法点击“立即购买”的按钮但是需要考虑的是,有人可以绕过前端的限制直接通过URL的方式发起购买,这就需要在前台商品页面以及bug页面到后端的数据库,都要进行时钟同步越在后端控制,安全性越高

定时抢秒杀软件的话,就要避免卖家在抢秒杀软件前对商品做编辑带来的不可预期的影响这种特殊的变更需要多方面评估。一般禁止编辑如需变更,可以走数据订正多的流程

有两种选择,┅种是拍下减库存 另外一种是付款减库存;目前采用的“拍下减库存”的方式拍下就是一瞬间的事,对用户体验会好些

库存会带来“超卖”的问题:售出数量多于库存数量

由于库存并发更新的问题,导致在实际库存已经不足的情况下库存依然在减,导致卖家的商品卖嘚件数超过抢秒杀软件的预期方案:采用乐观锁

抢秒杀软件器一般下单个购买及其迅速,根据购买记录可以甄别出一部分可以通过校驗码达到一定的方法,这就要求校验码足够安全不被破解,采用的方式有:抢秒杀软件专用验证码电视公布验证码,抢秒杀软件答题

尽量将请求拦截在系统上游

传统抢秒杀软件系统之所以挂,请求都压倒了后端数据层数据读写锁冲突严重,并发高响应慢几乎所有請求都超时,流量虽大下单成功的有效流量甚小【一趟火车其实只有2000张票,200w个人来买基本没有人能买成功,请求有效率为0】

读多写尐的常用多使用缓存

这是一个典型的读多写少的应用场景【一趟火车其实只有2000张票,200w个人来买最多2000个人下单成功,其他人都是查询库存写比例只有0.1%,读比例占99.9%】非常适合使用缓存。

抢秒杀软件系统为抢秒杀软件而设计不同于一般的网购行为,参与抢秒杀软件活动的鼡户更关心的是如何能快速刷新商品页面在抢秒杀软件开始的时候抢先进入下单页面,而不是商品详情等用户体验细节因此抢秒杀软件系统的页面设计应尽可能简单。

商品页面中的购买按钮只有在抢秒杀软件活动开始的时候才变亮在此之前及抢秒杀软件商品卖出后,該按钮都是灰色的不可以点击。

下单表单也尽可能简单购买数量只能是一个且不可以修改,送货地址和付款方式都使用用户默认设置没有默认也可以不填,允许等订单提交后修改;只有第一个提交的订单发送给网站的订单子系统其余用户提交订单后只能看到抢秒杀軟件结束页面。

要做一个这样的抢秒杀软件系统业务会分为两个阶段,第一个阶段是抢秒杀软件开始前某个时间到抢秒杀软件开始 这個阶段可以称之为准备阶段,用户在准备阶段等待抢秒杀软件; 第二个阶段就是抢秒杀软件开始到所有参与抢秒杀软件的用户获得抢秒杀軟件结果 这个就称为抢秒杀软件阶段吧。

首先要有一个展示抢秒杀软件商品的页面 在这个页面上做一个抢秒杀软件活动开始的倒计时, 在准备阶段内用户会陆续打开这个抢秒杀软件的页面 并且可能不停的刷新页面。这里需要考虑两个问题:

第一个是抢秒杀软件页面的展示

我们知道一个html页面还是比较大的即使做了压缩,http头和内容的大小也可能高达数十K加上其他的css, js图片等资源,如果同时有几千万囚参与一个商品的抢购一般机房带宽也就只有1G~10G,网络带宽就极有可能成为瓶颈所以这个页面上各类静态资源首先应分开存放,然后放箌cdn节点上分散压力由于CDN节点遍布全国各地,能缓冲掉绝大部分的压力而且还比机房带宽便宜~

出于性能原因这个一般由js调用客户端本地時间,就有可能出现客户端时钟与服务器时钟不一致另外服务器之间也是有可能出现时钟不一致。客户端与服务器时钟不一致可以采用愙户端定时和服务器同步时间这里考虑一下性能问题,用于同步时间的接口由于不涉及到后端逻辑只需要将当前web服务器的时间发送给愙户端就可以了,因此速度很快就我以前测试的结果来看,一台标准的web服务器2W+QPS不会有问题如果100W人同时刷,100W QPS也只需要50台web一台硬件LB就可鉯了~,并且web服务器群是可以很容易的横向扩展的(LB+DNS轮询)这个接口可以只返回一小段json格式的数据,而且可以优化一下减少不必要cookie和其他http头的信息所以数据量不会很大,一般来说网络不会成为瓶颈即使成为瓶颈也可以考虑多机房专线连通,加智能DNS的解决方案;web服务器之间时間不同步可以采用统一时间服务器的方式比如每隔1分钟所有参与抢秒杀软件活动的web服务器就与时间服务器做一次时间同步。

(1)产品层媔用户点击“查询”或者“购票”后,按钮置灰禁止用户重复提交请求;

(2)JS层面,限制用户在x秒之内只能提交一次请求;

前端层的请求攔截只能拦住小白用户(不过这是99%的用户哟),高端的程序员根本不吃这一套写个for循环,直接调用你后端的http请求怎么整?

(1)同一個uid限制访问频度,做页面缓存x秒内到达站点层的请求,均返回同一页面

(2)同一个item的查询例如手机车次,做页面缓存x秒内到达站點层的请求,均返回同一页面

如此限流又有99%的流量会被拦截在站点层。

站点层的请求拦截只能拦住普通程序员,高级黑客假设他控淛了10w台肉鸡(并且假设买票不需要实名认证),这下uid的限制不行了吧怎么整?

(1)大哥我是服务层,我清楚的知道小米只有1万部手机我清楚的知道一列火车只有2000张车票,我透10w个请求去数据库有什么意义呢对于写请求,做请求队列每次只透过有限的写请求去数据层,如果均成功再放下一批如果库存不够则队列里的写请求全部返回“已售完”;

(2)对于读请求,还用说么cache来抗,不管是memcached还是redis单机忼个每秒10w应该都是没什么问题的;

如此限流,只有非常少的写请求和非常少的读缓存mis的请求会透到数据层去,又有99.9%的请求被拦住了

用戶请求分发模块:使用Nginx或Apache将用户的请求分发到不同的机器上。
用户请求预处理模块:判断商品是不是还有剩余来决定是不是要处理该请求
用户请求处理模块:把通过预处理的请求封装成事务提交给数据库,并返回是否成功
数据库接口模块:该模块是数据库的唯一接口,負责与数据库交互提供RPC接口供查询是否抢秒杀软件结束、剩余数量等信息。

经过HTTP服务器的分发后单个服务器的负载相对低了一些,但總量依然可能很大如果后台商品已经被抢秒杀软件完毕,那么直接给后来的请求返回抢秒杀软件失败即可不必再进一步发送事务了,礻例代码可以如下所示:

* 预处理阶段把不必要的请求直接驳回,必要的请求添加到队列中进入下一阶段.

* 每一个HTTP请求都要经过该预处理.

ArrayBlockingQueue是初始容量固定的阻塞队列我们可以用来作为数据库模块成功竞拍的队列,比如有10个商品那么我们就设定一个10大小的数组队列。

ConcurrentLinkedQueue使用的昰CAS原语无锁队列实现是一个异步队列,入队的速度很快出队进行了加锁,性能稍慢

LinkedBlockingQueue也是阻塞的队列,入队和出队都用了加锁当队涳的时候线程会暂时阻塞。

由于我们的系统入队需求要远大于出队需求一般不会出现队空的情况,所以我们可以选择ConcurrentLinkedQueue来作为我们的请求隊列实现:

* 发送抢秒杀软件事务到数据库队列.

数据库主要是使用一个ArrayBlockingQueue来暂存有可能成功的用户请求

* DB应该是数据库的唯一接口.

分片解决的昰“数据量太大”的问题,也就是通常说的“水平切分”一旦引入分片,势必有“数据路由”的概念哪个数据访问哪个库。路由规则通常有3种方法:

缺点:各库压力不均(新号段更活跃)

哈希:hash 【大部分互联网公司采用的方案二:哈希分库哈希路由】

优点:简单,数據均衡负载均匀

缺点:迁移麻烦(2库扩3库数据要迁移)

优点:灵活性强,业务与路由算法解耦

缺点:每次访问数据库前多一次查询

分组解决“可用性”问题分组通常通过主从复制的方式实现。

互联网公司数据库实际软件架构是:又分片又分组(如下图)

数据库软件架構师平时设计些什么东西呢?至少要考虑以下四点:

如何提高数据库读性能(大部分应用读多写少读会先成为瓶颈);

1. 如何保证数据的鈳用性?

解决可用性问题的思路是=>冗余

如何保证站点的可用性复制站点,冗余站点

如何保证服务的可用性复制服务,冗余服务

如何保證数据的可用性复制数据,冗余数据

数据的冗余会带来一个副作用=>引发一致性问题(先不说一致性问题,先说可用性)

2. 如何保证数據库“读”高可用?

冗余读库带来的副作用读写有延时,可能不一致

上面这个图是很多互联网公司的架构写仍然是单点,不能保证写高可用

3. 如何保证数据库“写”高可用?

采用双主互备的方式可以冗余写库带来的副作用?双写同步数据可能冲突(例如“自增id”同步冲突),如何解决同步冲突,有两种常见解决方案:

两个写库使用不同的初始值相同的步长来增加id:1写库的id为0,2,4,6…;2写库的id为1,3,5,7…;
不使用數据的id,业务层自己生成唯一的id保证数据不冲突;
实际中没有使用上述两种架构来做读写的“高可用”,采用的是“双主当主从用”的方式:

仍是双主但只有一个主提供服务(读+写),另一个主是“shadow-master”只用来保证高可用,平时不提供服务 master挂了,shadow-master顶上(vip漂移对业务層透明,不需要人工介入)这种方式的好处:

不能通过加从库的方式扩展读性能;
资源利用率为50%,一台冗余主没有提供服务;
那如何提高读性能呢进入第二个话题,如何提供读性能

提高读性能的方式大致有三种,第一种是建立索引这种方式不展开,要提到的一点是不同的库可以建立不同的索引。

线上读库建立线上访问索引例如uid;

线下读库建立线下访问索引,例如time;

第二种扩充读性能的方式是增加从库,这种方法大家用的比较多但是,存在两个缺点:

同步越慢数据不一致窗口越大(不一致后面说,还是先说读性能的提高);
实际中没有采用这种方法提高数据库读性能(没有从库)采用的是增加缓存。常见的缓存架构如下:

上游是业务应用下游是主库,從库(读写分离)缓存。

实际的玩法:服务+数据库+缓存一套

业务层不直接面向db和cache服务层屏蔽了底层db、cache的复杂性。为什么要引入服务层今天不展开,采用了“服务+数据库+缓存一套”的方式提供数据访问用cache提高读性能。

不管采用主从的方式扩展读性能还是缓存的方式擴展读性能,数据都要复制多份(主+从db+cache),一定会引发一致性问题

5. 如何保证一致性?

主从数据库的一致性通常有两种解决方案:

如果某一个key有写操作,在不一致时间窗口内中间件会将这个key的读操作也路由到主库上。这个方案的缺点是数据库中间件的门槛较高(百喥,腾讯阿里,360等一些公司有)

上面实际用的“双主当主从用”的架构,不存在主从不一致的问题

第二类不一致,是db与缓存间的不┅致:

常见的缓存架构如上此时写操作的顺序是:

(3)读从库后,将数据放回cache;

在一些异常时序情况下有可能从【从库读到旧数据(哃步还没有完成),旧数据入cache后】数据会长期不一致。解决办法是“缓存双淘汰”写操作时序升级为:

(3)在经验“主从同步延时窗ロ时间”后,再次发起一个异步淘汰cache的请求;

这样即使有脏数据如cache,一个小的时间窗口之后脏数据还是会被淘汰。带来的代价是多引入一次读miss(成本可以忽略)。

除此之外最佳实践之一是:建议为所有cache中的item设置一个超时时间。

6. 如何提高数据库的扩展性

原来用hash的方式路由,分为2个库数据量还是太大,要分为3个库势必需要进行数据迁移,有一个很帅气的“数据库秒级扩容”方案

首先,我们不做2庫变3库的扩容我们做2库变4库(库加倍)的扩容(未来4->8->16)

服务+数据库是一套(省去了缓存),数据库采用“双主”的模式

第一步,将一個主库提升;

第二步修改配置,2库变4库(原来MOD2现在配置修改后MOD4),扩容完成;

原MOD2为偶的部分现在会MOD4余0或者2;原MOD2为奇的部分,现在会MOD4余1戓者3;数据不需要迁移同时,双主互相同步一遍是余0,一边余2两边数据同步也不会冲突,秒级完成扩容!

最后要做一些收尾工作:

增加新的双主(双主是保证可用性的,shadow-master平时不提供服务);

删除多余的数据(余0的主可以将余2的数据删除掉);

这样,秒级别内我們就完成了2库变4库的扩展。

5.1 请求接口的合理设计

一个抢秒杀软件或者抢购页面通常分为2个部分,一个是静态的HTML等内容另一个就是参与搶秒杀软件的Web后台请求接口。

通常静态HTML等内容是通过CDN的部署,一般压力不大核心瓶颈实际上在后台请求接口上。这个后端接口必须能够支持高并发请求,同时非常重要的一点,必须尽可能“快”在最短的时间里返回用户的请求结果。为了实现尽可能快这一点接ロ的后端存储使用内存级别的操作会更好一点。仍然直接面向MySQL之类的存储是不合适的如果有这种复杂业务的需求,都建议采用异步写入


当然,也有一些抢秒杀软件和抢购采用“滞后反馈”就是说抢秒杀软件当下不知道结果,一段时间后才可以从页面中看到用户是否抢秒杀软件成功但是,这种属于“偷懒”行为同时给用户的体验也不好,容易被用户认为是“暗箱操作”

5.2 高并发的挑战:一定要“快”

我们通常衡量一个Web系统的吞吐率的指标是QPS(Query Per Second,每秒处理请求数)解决每秒数万次的高并发场景,这个指标非常关键举个例子,我们假设处理一个业务请求平均响应时间为100ms同时,系统内有20台Apache的Web服务器配置MaxClients为500个(表示Apache的最大连接数目)。

那么我们的Web系统的理论峰值QPS為(理想化的计算方式):

咦?我们的系统似乎很强大1秒钟可以处理完10万的请求,5w/s的抢秒杀软件似乎是“纸老虎”哈实际情况,当然沒有这么理想在高并发的实际场景下,机器都处于高负载的状态在这个时候平均响应时间会被大大增加。

就Web服务器而言Apache打开了越多嘚连接进程,CPU需要处理的上下文切换也越多额外增加了CPU的消耗,然后就直接导致平均响应时间增加因此上述的MaxClient数目,要根据CPU、内存等硬件因素综合考虑绝对不是越多越好。可以通过Apache自带的abench来测试一下取一个合适的值。然后我们选择内存操作级别的存储的Redis,在高并發的状态下存储的响应时间至关重要。网络带宽虽然也是一个因素不过,这种请求数据包一般比较小一般很少成为请求的瓶颈。负載均衡成为系统瓶颈的情况比较少在这里不做讨论哈。

那么问题来了假设我们的系统,在5w/s的高并发状态下平均响应时间从100ms变为250ms(实際情况,甚至更多):

于是我们的系统剩下了4w的QPS,面对5w每秒的请求中间相差了1w。

然后这才是真正的恶梦开始。举个例子高速路口,1秒钟来5部车每秒通过5部车,高速路口运作正常突然,这个路口1秒钟只能通过4部车车流量仍然依旧,结果必定出现大塞车(5条车噵忽然变成4条车道的感觉)。

同理某一个秒内,20*500个可用连接进程都在满负荷工作中却仍然有1万个新来请求,没有连接进程可用系统陷入到异常状态也是预期之内。


其实在正常的非高并发的业务场景中也有类似的情况出现,某个业务请求接口出现问题响应时间极慢,将整个Web请求响应时间拉得很长逐渐将Web服务器的可用连接数占满,其他正常的业务请求无连接进程可用。

更可怕的问题是是用户的荇为特点,系统越是不可用用户的点击越频繁,恶性循环最终导致“雪崩”(其中一台Web机器挂了导致流量分散到其他正常工作的机器仩,再导致正常的机器也挂然后恶性循环),将整个Web系统拖垮

5.3 重启与过载保护

如果系统发生“雪崩”,贸然重启服务是无法解决问題的。最常见的现象是启动起来后,立刻挂掉这个时候,最好在入口层将流量拒绝然后再将重启。如果是redis/memcache这种服务也挂了重启的時候需要注意“预热”,并且很可能需要比较长的时间

抢秒杀软件和抢购的场景,流量往往是超乎我们系统的准备和想象的这个时候,过载保护是必要的如果检测到系统满负载状态,拒绝请求也是一种保护措施在前端设置过滤是最简单的方式,但是这种做法是被鼡户“千夫所指”的行为。更合适一点的是将过载保护设置在CGI入口层,快速将客户的直接请求返回

6 ***的手段:进攻与防守

抢秒杀软件和抢购收到了“海量”的请求,实际上里面的水分是很大的不少用户,为了“抢“到商品会使用“刷票工具”等类型的辅助工具,幫助他们发送尽可能多的请求到服务器还有一部分高级用户,制作强大的自动请求脚本这种做法的理由也很简单,就是在参与抢秒杀軟件和抢购的请求中自己的请求数目占比越多,成功的概率越高

这些都是属于“***的手段”,不过有“进攻”就有“防守”,这昰一场没有硝烟的战斗哈

6.1 同一个账号,一次性发出多个请求

部分用户通过浏览器的插件或者其他工具在抢秒杀软件开始的时间里,以洎己的账号一次发送上百甚至更多的请求。实际上这样的用户破坏了抢秒杀软件和抢购的公平性。

这种请求在某些没有做数据安全处悝的系统里也可能造成另外一种破坏,导致某些判断条件被绕过例如一个简单的领取逻辑,先判断用户是否有参与记录如果没有则領取成功,最后写入到参与记录中这是个非常简单的逻辑,但是在高并发的场景下,存在深深的漏洞多个并发请求通过负载均衡服務器,分配到内网的多台Web服务器它们首先向存储发送查询请求,然后在某个请求成功写入参与记录的时间差内,其他的请求获查询到嘚结果都是“没有参与记录”这里,就存在逻辑判断被绕过的风险


在程序入口处,一个账号只允许接受1个请求其他请求过滤。不仅解决了同一个账号发送N个请求的问题,还保证了后续的逻辑流程的安全实现方案,可以通过Redis这种内存缓存服务写入一个标志位(只尣许1个请求写成功,结合watch的乐观锁的特性)成功写入的则可以继续参加。

或者自己实现一个服务,将同一个账号的请求放入一个队列Φ处理完一个,再处理下一个

6.2 多个账号,一次性发送多个请求

很多公司的账号注册功能在发展早期几乎是没有限制的,很容易就可鉯注册很多个账号因此,也导致了出现了一些特殊的工作室通过编写自动注册脚本,积累了一大批“僵尸账号”数量庞大,几万甚臸几十万的账号不等专门做各种刷的行为(这就是微博中的“僵尸粉“的来源)。举个例子例如微博中有转发抽奖的活动,如果我们使用几万个“僵尸号”去混进去转发这样就可以大大提升我们中奖的概率。

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


这种场景可以通过检测指定机器IP请求频率就可以解决,如果发现某个IP请求频率很高可以给它弹出┅个验证码或者直接禁止它的请求:

弹出验证码,最核心的追求就是分辨出真实用户。因此大家可能经常发现,网站弹出的验证码囿些是“鬼神乱舞”的样子,有时让我们根本无法看清他们这样做的原因,其实也是为了让验证码的图片不被轻易识别因为强大的“洎动脚本”可以通过图片识别里面的字符,然后让脚本自动填写验证码实际上,有一些非常创新的验证码效果会比较好,例如给你一個简单问题让你回答或者让你完成某些简单操作(例如百度贴吧的验证码)。
直接禁止IP实际上是有些粗暴的,因为有些真实用户的网絡场景恰好是同一出口IP的可能会有“误伤“。但是这一个做法简单高效根据实际场景使用可以获得很好的效果。

6.3 多个账号不同IP发送鈈同请

所谓道高一尺,魔高一丈有进攻,就会有防守永不休止。这些“工作室”发现你对单机IP请求频率有控制之后,他们也针对這种场景想出了他们的“新进攻方案”,就是不断改变IP

有同学会好奇,这些随机IP服务怎么来的有一些是某些机构自己占据一批独立IP,然后做成一个随机代理IP的服务有偿提供给这些“工作室”使用。还有一些更为黑暗一点的就是通过木马黑掉普通用户的电脑,这个朩马也不破坏用户电脑的正常运作只做一件事情,就是转发IP包普通用户的电脑被变成了IP代理出口。通过这种做法黑客就拿到了大量嘚独立IP,然后搭建为随机IP服务就是为了挣钱。

说实话这种场景下的请求,和真实用户的行为已经基本相同了,想做分辨很困难再莋进一步的限制很容易“误伤“真实用户,这个时候通常只能通过设置业务门槛高来限制这种请求了,或者通过账号行为的”数据挖掘“来提前清理掉它们

僵尸账号也还是有一些共同特征的,例如账号很可能属于同一个号码段甚至是连号的活跃度不高,等级低资料鈈全等等。根据这些特点适当设置参与门槛,例如限制参与抢秒杀软件的账号等级通过这些业务手段,也是可以过滤掉一些僵尸号

7 高并发下的数据安全

我们知道在多线程写入同一个文件的时候,会存现“线程安全”的问题(多个线程同时运行同一段代码如果每次运荇结果和单线程运行的结果是一样的,结果和预期相同就是线程安全的)。如果是MySQL数据库可以使用它自带的锁机制很好的解决问题,泹是在大规模并发的场景中,是不推荐使用MySQL的抢秒杀软件和抢购的场景中,还有另外一个问题就是“超发”,如果在这方面控制不慎会产生发送过多的情况。我们也曾经听说过某些电商搞抢购活动,买家成功拍下后商家却不承认订单有效,拒绝发货这里的问題,也许并不一定是商家奸诈而是系统技术层面存在超发风险导致的。

假设某个抢购场景中我们一共只有100个商品,在最后一刻我们巳经消耗了99个商品,仅剩最后一个这个时候,系统发来多个并发请求这批请求读取到的商品余量都是99个,然后都通过了这一个余量判斷最终导致超发。


在上面的这个图中就导致了并发用户B也“抢购成功”,多让一个人获得了商品这种场景,在高并发的情况下非常嫆易出现

解决线程安全的思路很多,可以从“悲观锁”的方向开始讨论

悲观锁,也就是在修改数据的时候采用锁定状态,排斥外部請求的修改遇到加锁的状态,就必须等待


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

那好,那么我们稍微修改一下上面的場景我们直接将请求放入队列中的,采用FIFO(First Input First Output先进先出),这样的话我们就不会导致某些请求永远获取不到锁。看到这里是不是有點强行将多线程变成单线程的感觉哈。

然后我们现在解决了锁的问题,全部请求采用“先进先出”的队列方式来处理那么新的问题来叻,高并发的场景下因为请求很多,很可能一瞬间将队列内存“撑爆”然后系统又陷入到了异常状态。或者设计一个极大的内存队列也是一种方案,但是系统处理完一个队列内请求的速度根本无法和疯狂涌入队列中的数目相比。也就是说队列内的请求会越积累越哆,最终Web系统平均响应时候还是会大幅下降系统还是陷入异常。

这个时候我们就可以讨论一下“乐观锁”的思路了。乐观锁是相对於“悲观锁”采用更为宽松的加锁机制,大都是采用带版本号(Version)更新实现就是,这个数据所有请求都有资格去修改但会获得一个该數据的版本号,只有版本号符合的才能更新成功其他的返回抢购失败。这样的话我们就不需要考虑队列的问题,不过它会增大CPU的计算开销。但是综合来说,这是一个比较好的解决方案

有很多软件和服务都“乐观锁”功能的支持,例如Redis中的watch就是其中之一通过这个實现,我们保证了数据的安全

互联网正在高速发展,使用互联网服务的用户越多高并发的场景也变得越来越多。电商抢秒杀软件和抢購是两个比较典型的互联网高并发场景。虽然我们解决问题的具体技术方案可能千差万别但是遇到的挑战却是相似的,因此解决问题嘚思路也异曲同工

  央广网太原11月17日消息(记者周益帆)据中国之声《新闻晚高峰》报道为了营销,不少网络购物平台都会推出 “抢秒杀软件”、“低价抢购”或者“新品抢购”等活動但是有消费者可能会遇到这样的情况:明明网速很快、也提前做好了准备,但就是抢不过其它人

  实际上,有一种可能是你在与“抢购软件”比赛这些“抢购软件”能够避开或者突破购物网站计算机信息系统安全保护措施,快速抢购到抢秒杀软件商品不少“黄犇党”就是用这样的软件抢购商品、从中牟利。其中一款名为“黑米”的软件被无数黄牛党奉为“神器”。近日山西太原市迎泽区人囻法院对“黑米天猫”软件的制作者、销售者判处有期徒刑并处罚金。这也是国内首个对制作、销售黄牛抢购软件者判刑的案件

  尽管“黑米”软件的三名制作者、销售者,因“提供侵入、非法控制计算机信息系统的程序、工具罪”被太原市迎泽区人民法院判处有期徒刑并处罚金。但在软件贴吧中仍然有人发帖询问,为何软件不能使用了

  通过贴吧中使用者的抢购晒单可以看出,“黑米”软件並非只有一款制作者开发了针对“天猫”、“华为”、“小米”等系列抢购软件。今年年初天猫发现平台交易流量异常,监测半个月の后报警阿里巴巴安全部网络安全资深专家王大鹏表示:“这一款软件使用的流量要远远高于普通流量,关注两周左右后报警处理”

  山西省太原市公安局迎泽区分局接到报警后,锁定了黑米的制作者任某、张某及销售者陈某协助案件侦破的网络安全专家王少华说:“黄牛市场现在是暴利,所这些软件为了防止同行破解或者抄袭都使用技术手段对软件进行了处理,我们在这方面花了一些时间”

  据了解,软件开发者任某从2014年起开始接触网络上的抢秒杀软件抢购活动此后,通过QQ群结识软件工程专业毕业的张某张某用一周的時间制作出黄牛软件――黑米,并在网上找到陈某制作黑米抢购软件官方网站、出售该软件。2015年任某、张某开发了专门针对天猫网站嘚黑米天猫(淘宝)抢购软件。王少华说黑米软件通过直接向服务器发送任务,完成抢购“‘黑米’软件主要是破解了各电商平台加密的下单协议,利用第三方打码平台服务直接绕过图片验证码安全识别策略,又利用更换IP、伪造设备编号等方式进一步绕过了电商系統的机器识别和防护,基于以上突破的手段使用软件的是直接向电商的服务器发送抢购任务,但是正常的用户都是点击浏览器或者手机愙户端上的按钮完成操作所以用这款软件的成功率要高一些。”

  通过这一软件任某、张某赚取买家抢购成功商品部分差价,陈某則通过建立“黑米”系列抢购软件销售网站、网站维护、代理销售该抢购软件非法获利经中国刑事***学院物证鉴定中心检验,黑米天貓软件为恶意程序今年8月,太原市迎泽区人民检察院以涉嫌提供侵入、非法控制计算机信息系统程序、工具罪对三名被告人提起公诉

  太原市迎泽区人民法院一审判处软件研发者任某和张某有期徒刑三年,缓刑四年并处罚金人民币三万元;销售者陈某有期徒刑二年,缓刑三年并处罚金人民币一万元。迎泽区人民法院研究室主任周玉旺介绍:“任某某等3人定罪量刑依据《刑法》第285条第2款、第3款该3囚违反国家规定,提供专门用于侵入、非法控制计算机信息系统的程序、工具侵犯了国家计算机信息系统的安全和管理秩序,构成提供侵入、非法控制计算机信息系统的程序、工具罪”

  黄牛抢购软件,影响了互联网交易的秩序而整个网络黑灰产业,更是严重侵害叻国家网络信息安全周玉旺认为,作为国内首个对制作、销售黄牛抢购软件者判刑的案件“黑米”的判例不仅打击了扰乱计算机管理秩序的犯罪行为,更起到了警示作用“这种犯罪方式更具隐蔽性,专业性侦查取证难度较大,严重侵害了国家网络信息安全本案对嫼灰产业软件工具制造者,即提供入侵、控制计算机信息系统软件的三名罪犯处以刑罚打击了扰乱计算机管理秩序的犯罪行为,警示他囚不得侵犯计算机管理秩序否则,将承担刑事责任”

为什么我现在用微信公众号的topsports限量发售预约资格码每次都是以后一步的时候提示当前抢兑人数太多,请稍后再试但是我是钻石会员,而且以前都不…

参考资料

 

随机推荐