所谓知已知彼,百战不殆,在开始详细介绍实战中的抢购秒杀系统时,咱们了解一些抢购秒杀系统系统面临的尴尬与难点。另外须要说明一点,下面的内容都是在工做中慢慢总结得来,咱们团队也是慢慢摸着石头过河,甚至最初的的架构设计并不是是抢购秒杀系统。php
理论基础:LNMP的并发考虑与资源分配html
虽然有基础去评估咱们应用系统的处理能力,可是电商购买的业务流程挺复杂,从登陆,商品详情,购物车,填写收货地址,选择支付方式,建立订单,完成支付,以及隐含的定时服务,限购策略,库存操做,排队机制等一系列的业务逻辑,每一个请求的处理时间都不同。那么根据木桶原理,一只水桶能将多少水取决于它最短的那块木板,分析整个业务流程中最耗系统资源的请求,以此为标准为评估系统处理能力。nginx
咱们是一个作特卖秒杀抢购的电商平台,咱们的商品异常火爆且价格低廉价,这就给网络黄牛带了巨大的利润空间。为了让真正的平台用户受益,改善用户体验,提升用户留存率,咱们在产品业务、技术实现上尝试了不少方法,都没有完美解决黄牛刷单的问题。算法
话说回来,让黄牛买不到商品,不是单纯技术可以解决的问题。咱们要解决的问题是,因为黄牛大规模的请求登陆接口、商品详情页接口、下单接口致使在抢购开始先后的流量峰值直接翻了上千倍,最终致使服务不可用。在不增长硬件成本的状况下,解决短期内大流量致使的服务不可用。后端
以H5应用为主站主要流量入口,支持QQ、微信、微博等平台用户登陆购买,嵌入到某流行的资讯客户端。另外,也有单独的特卖安卓客户端、IOS客户端。浏览器
黄牛每次抢购活动注册新用户,因为平台流量大部分来自某新闻客户端,客户端的帐号体系为弱帐号体系,能够绑定手机号也能够解除绑定,每次从新绑定都会生成新的用户ID。同时平台也容许非手机号注册的用户下单购买商品,用户的收货地址的联系电话能够和注册帐号的手机号不一致。另外一方面,黄牛在淘宝花钱能够购买大量的平台新注册帐号,真是术业有专攻。缓存
在云服务盛行的互联网时代,黄牛以很低的成本能够得到上万的IP及主机,IP分布在全球各地。服务器
黄牛刷单时访问频次不是很高,在拥有大量帐号、IP的状况下,访问频次低也能够抢购到商品。微信
黄牛的技术很强,将混淆加密后的原生客户端破解,将其中的加密算法重写,升级抢购软件。网络
黄牛为了不预定用户将商品提早抢光,联合全国的黄牛同时高频次的访问网站数据接口,致使网站因为大流量下不堪重负,从而服务不可用,在预定提早购买时间过去(黄牛的目的是堵住预定用户购买),全网用户都可购买时,慢慢的减小流量,任意下单购买商品。
全网用户提早预定,具备预定购买资格的用户可享受提早入场下单购买。预定须要绑定手机号,输入验证码(短信和图片)。
为了应对短期内的大流量请求,采用排队购买机制,用户提交购买请求后当即返回,等待后端处理结果。
在预知大流量不可控时,将H5主站流量引到原生的客户端APP内进行抢购。
在抢购开始时,下单购买某商品必须输入验证码。在必定时间内,对于访问库存为0的用户请求,超过必定频次后要求输入验证码。打码云服务不少,理论上字符验证码都可识别,甚至人工打码,可是提升了刷单成本。
经过nginx的lua扩展,在单位时间内同用户相同IP请求同一URL进行计数,在nginx层面进行限流。IP级别下,控制很差,误杀太多或者起不了做用。
设定PHP可并发处理请求的最大值,nginx交给PHP的请求都进行计数+1,fastcgi完成后进行-1。因为nginx+php-fpm高并发状况下,作到原子的计数很难。
引入消息队列和长链接服务,用户请求排队购买,后端进行流量控制,发放资格号,经过长链接通知用户的处理结果。
将商品详情页静态化,静态页面的请求直接由CDN返回。
通过几回大规模的抢购后,黄牛帐号有限,将积累的黄牛帐号入库,在下次抢购时,载入内存,下降购买优先级或者直接拒绝请求。
从原有的几台服务器,扩容到几十台服务器,每一个服务都部署负载均衡、高可用。如多级缓存、nginx与php-fpm分离、长链接服务器集群等等。
抢购开始前准备上百倍的服务器数量,全部的服务都可横向扩展,提升处理能力。
上面交待了挺多的作抢购平台的一些场景、特征、措施,涉及的产品和技术的面广,我认为最重要的是解决网站服务不可用或者宕机的问题,咱们在nginx层面作了不少努力与尝试,另外nginx在防CC攻击方面有一些成熟的方案,下面详述,下一阶段研究nginx源码。
限制链接数模块
一般用来限制同一IP地址的可并发链接数
指令说明:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
须要注意的是$binary_remote_addr而不是$remote_addr,$remote_addr的长度为7到15个字节,它的会话信息的长度为32或64 bytes,$binary_remote_addr的长度为4字节,会话信息的长度为32字节,这样设置1M的一个zone时,用$binary_remote_addr方式,该zone将会存放32000个会话。
限制请求数模块
一般用来限制同一IP地址单位时间可完成的请求数,限制的方法是采用漏桶算法(Leaky Bucket),每秒处理固定请求数量,推迟过多请求,超过桶的阀值,请求直接终止返回503。
指令说明:http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
nginx相似,不过支持多个变量,而且支持多个limit_req_zone及forbid_action的设置。
指令说明:http://tengine.taobao.org/document_cn/http_limit_req_cn.html
称之为基于条件的限速功能,在Tenginer的limit_req模块基础上,增长condition参数,在条件为真时执行限制动做。
称之为行为识别模块,访问行为识别模块的做用是对用户访问网站的行为进行监控
指令说明:http://www.senginx.org/cn/index.php/Robot_Mitigation%E6%A8%A1%E5%9D%97
称之为HTTP机器人缓解,Robot Mitigation模块采用了一种基于“挑战”的验证方法,即向客户端发送特定的、浏览器能解析的应答,若是客户端是真实的浏览器,则会从新触发请求, 并带有一个特定的Cookie值,Robot Mitigation模块会依据此Cookie的信息来决定是否放行此请求。
基于上述的场景、特征、nginx限制模块的调研和分析,咱们彻底能够经过灵活的nginx配置来解决CC攻击威胁。使用了Senginx,灵活运用基于条件的限速功能,行为识别模块,机器人缓解模块。今天先聊到这儿,后续会总结出本文提到的不少技术细节。