大流量下的高效管控
在“秒杀”场景中,海量用户带来的流量高峰,会给服务端带来读写性能问题,数据库锁,以及服务器资源占用问题。
“秒杀”场景往往希望有大量用户关注活动,但是用户真正下单时,有不能讲这些流量全部放过。所以需要设计一套高效的管控方案,有效的控制请求流量以及过滤掉没必要的流量。
流量分层
对于响应速度,将数据放在静态缓存中是一个不错的处理。但是,业务特性决定了不能永远将数据放在静态缓存中。所以一般会对流量进行分层控制。
一般分为以下几个层级:CDN,Nginx,后端服务,数据库。
注意:在部分的场景中,用户的浏览器也可以进行以及数据魂村:浏览器是最接近客户的,对于时效较长且体积不大的静态数据,可以将其放入浏览器的本地缓存中。(吐槽一下,公司刚招的前端,不会这个。。。)
流量分层控制
-
CDN层控制
由动静分离技术可以想到:应提前生成尽可能多的数据,然后将其放入CDN节点缓存中。如果大部分的流量都在这一层获取数据,那到达后端的流量就会减少很多。
-
反向代理层控制(nginx)
“页面静态化”技术可以加速动态数据的获取,提前将动态数据生成好,然后对其进行静态化处理。
例如:我最常用的,通过后端服务Job的方式定时提前生成好前端需要的静态数据,然后将其发送到对应的服务上,如果反向代理服务器很多的情况下,可以用专门的内容分发服务去分发给所有的反向代理服务器。
注意:分发静态数据时,可以根据具体的业务场景进行定时更新。例如:“秒杀”场景中关于商品详细信息的更新。除分发外,还可以利用Nginx 的缓存配置功能配置后端接口获取热点数据进行缓存。(我暂时还没有这么用过)
“秒杀”活动的倒计时可以直接使用Nginx来实现,利用nginx-lua插件,使用Lua脚本获取当前Nginx服务器的时间来计算倒计时。另外库存数据也可以通过Nginx直接访问分布式缓存来获取。
除此之外,秒杀活动中最常见的还有部分人利用“秒杀器”进行不公平竞争,对于这种恶意请求,最好有一套机制能够提前感知,将其封存。可以在Nginx层中控制,也可以在Nginx中配置用户的访问频率(例如每分钟最多10次),还可以使用Lua脚本编写一些简单的业务逻辑接口,例如,通过调用接口直接封掉IP地址。
注意:此处还可以利用大数据的日志手机组件(比如Flume)从Nginx上采集日志,将采集的日志写入存储系统中,然后风控平台对存储系统中的日志进行锋线分析。对于有风险的请求,风控平台可以直接调用Nginx中的Lua脚本接口对其进行封停处理。
-
后端服务层流量控制
对于后端服务的流量控制,尽量做到以下几点:
-
程序开发上,代码独立,不要与平台其他项目合在一起
-
在部署时,应用独立部署,分散流量,避免不合适的流量影响主体业务
-
使用独立域名,或者按照一定的URL规则在反向代理层进行路由
-
做好系统保护以及限流,减少不必要的流量
当“请求数”明显大于“系统能够处理的最大请求数”时,可以直接拒绝多余的流量,提示用户活动已结束。
-
-
数据库层的流量控制
写数据库的流量就是真正下单成功的流量,需要扣减库存的动作,也有几点需要注意:
- 如果不是临时活动,建议使用独立的数据库作为秒杀活动的数据库
- 将数据库配置成读写分离
- 尝试去除行锁
对于数据库行锁的优化,可以通过将商品进行拆分来实现,对于单一的秒杀活动效果显著,如下所示:
商品ID 商品名称 库存数量 10000 某品牌商品 3 拆分成:
拆分ID 商品ID 库存数量 10000A1 10000 1 10000A2 10000 1 10000A3 10000 1