大浏览量系统的静态化架构设计

  1. 引言 

Web开发如何应对大流量是必须考虑的问题,例如当前的12306网站、淘宝的秒杀系统等都是Web系统会遇到的典型问题。尤其是一些突发流量更是会考验我们系统抗压的能力,所以在设计系统时要考虑很多因素,例如网络结构,网卡瓶颈,系统依赖,缓存,数据一致性等。所以接下来将以淘宝为例,讲述如何大浏览量的系统的静态化架构。

  1. 淘宝大浏览量商品详情系统简介

什么是大浏览量系统?以java系统为例,正常的用户请求要支撑20w/sQPS(每秒查询率)。根据Alexa全球排名,淘宝目前排名第13位,日均PVPage View)约有25亿,日均独立IP访问约有1.5亿,其中item.taobao.com域名对应的Detail系统约占总PV25%。可以说Detail系统是目前淘宝中单系统访问量最高的系统,当前每秒约有20KB的请求到达淘宝的服务器后端。

下面介绍这个大浏览量系统的基本情况:

页面大小45KB,压缩后15KB,峰值带宽2Gbps,服务端页面平均RT15ms.

静态化改造之前,淘宝的前台系统结构:

 

1.前台系统基本结构

前面的Http请求经过负载均衡设备分配到某个域名对应的应用集群,经过Nginx代理到JBoss或者Tomcat容器,由他们负责具体处理用户的请求。目前这些大浏览量的系统大部分需要读取的数据都已经直接走K/V缓存了,不会直接从DB中获取数据。还有一部分应用逻辑会走远程的系统调用。淘宝有一套高性能的分布式服务架构(HSF框架)来提供系统之间的服务调用。

目前淘宝前台系统都是基于JavaMVC框架开发的(自己的WebX框架)如图所示:

 

2.前台系统基本结构

  1. 系统面临的挑战

随着淘宝网站的壮大,系统也面临越来越多的挑战,有些是业务发展带来的挑战,比如双1112的大型活动,秒杀活动等突发流量的冲击。还有一些非正常的访问请求,例如网站经常受到攻击和恶意请求。这些流量有些是可以预测的,有些是不可预测的,不可防范的。

像这种流量突然暴增的情况对系统的冲击很大,有时候流量瞬间可达20w/sQPS,所以如何让系统更好更稳定的运行是一个大的挑战。

  1. 大浏览量的系统的静态化改造

4.1 静态化系统

静态化系统通常包含如下几方面的特征。

·一个页面对应的URL通常是固定的。

·页面中不能包含于浏览者相关的因素。

·页面中不包含时间因素。服务端输出的时间

·页面中不包含地域因素。

·不包含Cookie等私有数据

4.2 为什么要进行静态化设计

前面我们分析了系统面临的各种挑战,这些挑战都涉及性能优化,那性能优化为什么要进行静态化这种架构设计呢?

因为,淘宝其实已经经历了很多次系统的迭代升级,比如09年的静态文件合并,前端页面异步化和JSON化,10年的去DB依赖,引入K/V缓存和11年优化Velocity,BigPipe等都是优化的例子,但是这只是从Java系统层面上的优化,改进思路也一直是怎么更快的获取数据,并更快的将数据返回给用户。但是当将系统所有数据全部缓存,然后将结果直接返回的时候我们的系统不能满足预期的目标,也就说Java系统不可能达到每秒上万的QPS

所以,我们判断Java系统本身已经达到瓶颈,那我们就必须跳过java系统,也就是让请求尽量不经过java系统,在前面的Web服务器层就直接返回是,所以,静态化这种架构就成了必然选择。

静态化系统改变了缓存方式,直接缓存Http连接而不是缓存数据,Web代理服务器根据请求URL直接取出对应的HTTP响应头和响应体直接返回,这个响应连Http都不用重新组装了。同样,http头也不一定需要解析,这样做到获取数据最快。还改变了缓存的地方,不是java层面的缓存了,而是web服务器层上做缓存,所以屏蔽了java层面的弱点。

4.3 如何改造动态系统

Detail系统为例。

动静分离:

·URL唯一化。Detail系统天然就是可以做到URL唯一化,因为可以以ID做唯一标识URL.

·分离于浏览者相关的因素,是否登陆与登陆信息等可以单独拆分,动态获取。

·分离时间因素,服务端输出的时间也可以动态获取。

·异步化地域因素。把Detail系统上的地域相关的做成异步方式来获取。

·去掉Cookie.

动态内容结构化:

将动态内容json化。对于Detail系统虽然商品信息可以缓存,不需要动态获取但是也可以将关键信息做成json的形式。

 

如何组装动态内容:

两种方式获取:ESICSI

ESIWeb代理服务器上做动态请求内容,并将请求插入到静态页面上去。对服务端性能有影响但是用户体验好。

CSI:发起一个异步JS单独向服务端获取动态内容。这种方式使服务端性能更好,但是稍有延迟,用户体验稍差。

4.4 几种静态化方案的设计与选择

考虑的问题:

·是否一致性hash分组?使用则可能会导致热点问题,导致网络瓶颈。

·是否使用ESI?使用对性能有影响,但用户体验好。

·是否使用物理机?内存更大,cpu更好,但是使集群相对集中,导致网络风险增加。

·谁来压缩,在哪压缩?增加Cache,必然增加数据的传输。

·网卡选择?成本问题。

根据这几个问题,可分别采用如下几个方案:

方案1 采用Nginx+Cache+Java结构的虚拟机单机部署

结构图如下:

 

3.Nginx+Cache+Java虚拟机单机部署结构图

这是最简单的静态化方案,只需要在正常的架构上加一层Cache就行,优缺点如下:

优点:

·没有网络瓶颈,不需要改造网络

·机器增加,没有网卡瓶颈

·机器数增多,故障风险减少

缺点:

·机器增加,缓存命中率下降

·缓存分散,失效难度增加

·CacheJBoss都会抢内存

这种方案虽然简单,但是能够解决热点商品的访问问题。

方案2  Nginx+Cache+Java结构实体机单机部署

结构图如下:

 

4.Nginx+Cache+Java实体机单机部署结构图

优点如下:

·没有网络瓶颈,内存大

·减少Vish机器,提升命中率

·减少Cache失效的压力

·减少Gzip的压缩

方案3 统一Cache

结构图如下:

 

5.统一Cache层架构

优点:

·减少多个应用接入使用Cache成本,接入的应用只维护自己的Java系统。

·统一Cache易于维护,比如配置,监控自动化。统一维护升级。

·共享内存最大化利用内存。

·有助于安全防护。

4.5 如何解决失效问题:

缓存问题解决了,接下来应该解决失效问题了,采用主动失效和被动失效相结合的方式。

被动失效:

主要采用处理模板变更和对时效性要求不高的数据失效,采用设置Cache时间的长度这种自动失效方式,同时也要开发后台管理界面手工失效这些cache.

主动失效:

·Cache失效中心监控数据库表的变化,发送失效请求

·Java系统发布,清空Cache

·Vm模板发布,清空Cache

失效中心通过监控关键数据对应表的变更来发送请求给Cache,从而清楚Cache,其逻辑图如下:

 

6.失效中心逻辑图

4.6 服务端的静态化方案的演变:CDN化(内容分发网络)

将动态系统静态化后,将Cache前移到CDN中,效果会更好。但是面临如下几个问题:

·失效问题。CDN分布很广,秒级的时间失效大量Cache难度很大

·命中率问题。CDN是分散的,Cache移到CDN中则命中率必然下降

·发布更新问题。业务发布和问题回滚排查也是需要考虑的方面。

解决方案:

失效问题:

类比服务端静态化的失效方案,对CDN也采用类似的方式设计级联失效结构,如图:

 

7.级联失效逻辑图

命中率问题:

既然所有的CDN上放Detail不可行,那么挑部分CDN节点即可。

节点条件:

·靠近访问量比较集中的地方

·离主站较远

·到主站的网络好且稳定

·容量大

  1. 总结

本次主要以淘宝的Detail为背景,介绍了静态化架构的设计,其中面临的问题和解决办法,虽然主要以Detail系统为例,但其实架构的设计思路对所有大型的系统都是适用的。

 

惭愧,一年就写了两篇博客,最近在找实习,又想到写博客了....

本次博客直接摘自许令波的深入分析JavaWeb技术内幕的最后一章。有兴趣的话大家可以去看看这本书,写的真的不错。

原文地址:https://www.cnblogs.com/Ugly-bear/p/8679302.html