天猫浏览型应用的CDN静态化架构演变

article/2025/10/10 19:53:28

转载自:http://zhu-zhiguo.iteye.com/blog/2145496

在天猫双11活动中,商品详情、店铺等浏览型系统,通常会承受超出日常数倍甚至数十倍的流量冲击。随着历年来双11流量的大幅增加, 每年这些浏览型系统都要面临容量评估、硬件扩容、性能优化等各类技术挑战。因此,架构方面的重点在于,如何能够利用合理成本应对瞬间飙高的峰值请求,并确 保活动完整周期中系统容量的可伸缩性、用户响应时间的稳定性,以及外部依赖系统出现问题时的高可用性。此外,作为最主要的页面流量承载体系,架构方面还需 考虑防爬攻击、流控容灾等安全、稳定的需求,并综合衡量网络带宽、硬件成本、缓存效率等各方面要素,找准平衡点,从而达到以不变应万变的理想效果。

        演进

        为此,自2011年起,以天猫商品详情系统为代表,天猫浏览型系统在架构上的主要工作之一就是通过静态化技术实现了动静态信息分离、利用缓存技 术存放静态化内容、利用少量动态数据异步加载填充。整个过程历经单机静态化、统一缓存接入,到2013年双11前彻底CDN化三个阶段(如图1所示),有 效解决了缓存命中率、流量自然分布、系统扩容简化、用户端响应速度等关键问题。

天猫浏览型应用的CDN静态化架构演变

图1  CDN化的三个阶段

        目前,天猫浏览型系统最新使用的这套基于CDN的静态化架构,可以满足高可用持续伸缩的原始预期,并包含如下特性。

  • 动静分离:HTML静态化和热点分离。
  • 分布式缓存体系:利用CDN节点分布式缓存。
  • 多级缓存机制:CDN两级+应用一级。
  • 统一服务静态化集群。
  • 一致性维持:主动失效&自动失效缓存机制。
  • 动态内容填充:能支持多种时效性动态内容填充方式。
  • 监控预警机制:流量、失效、命中率等关键参数实时监控报警。

        本文将针对这一优化历程,就主要技术挑战、架构改造策略、最终优化成果做一个总览式的介绍,并重点对CDN化过程中整体架构的演进、缓存失效机制、动态内容填充等具体要点进行论述。

        第一阶段:系统静态化

        早期天猫浏览型系统大多采用简单架构,实现一层很薄的前台应用。以天猫商品详情系统为例,针对商品、用户等访问量较大的数据中心接口模式改造为 应用Client端缓存前置,同时普遍使用页面高速缓存(PageCache)来降低后端系统压力,使得整体可支持应用水平扩展不受限制。这一阶段系统面 临的主要问题和挑战包括以下几点:

  • 应用服务器瓶颈,页面渲染带来的CPU开销巨大。
  • 单纯基于Java端的缓存已基本覆盖,整体性能提升空间有限。
  • 水平扩容只能支持容量线性提升,难以满足大促井喷式流量增长,扩容成本高。

        从问题看,基于原有动态浏览型系统模式而优化的瓶颈很难规避,例如以下几点:

  • Java应用服务器端必要开销,包括:涉及页面内容的字符串查找、替换、拼接等;元数据获取的网络开销;Servlet本身的性能瓶颈。
  • Web服务器端,包括:模块过滤,例如访问日志、Cookie打点、繁简转换;大HTML页面本身的GZIP压缩等。
  • 突发流量的抵御,例如攻击、秒杀、大促,等等。
  • 已用优化手段达到了边界,包括:可使用缓存的地方已经使用;服务端CPU能力已优化完毕(模板解析、压缩)。

        总体来看,必须从架构着手彻底解决。架构优化的方向上,考虑以下3个方面:

  • 改变缓存方式,直接缓存HTTP响应结果。
  • 改变缓存位置,直接基于Web服务器,屏蔽业务逻辑。
  • 基本原则,缓存空间足够大、无单点、易于维护。

        为此,2012年起正式启动了动态浏览型系统的改造项目,通过静态化手段解决上述问题。即基于业务把原动态系统中的内容做动静分离,对浏览者无 关部分做缓存,动态内容做CSI填充。具体考虑从三方面重点着手展开:动静信息分离、静态化缓存方式,以及缓存失效机制。图2为一期静态化整体架构。

天猫浏览型应用的CDN静态化架构演变

图2  一期静态化整体架构

        动静分离

        将原页面内容按业务进行区分,从浏览用户、信息发布者、时间、地域、私有(Cookie等)信息等维度分析,抽取出页面中相对公共不依赖以上因 素,且变化频度较低的内容作为基础,生成静态化内容。静态化后页面URL固定,不同URL表示不同内容,服务器返回的请求与URL相关,其他动态内容则通 过异步接口调用,通过CSI方式填充。以商品详情系统为例,静态化后商品基本信息如标题、商品详情、销售属性组合等信息均直接进入缓存,其他如优惠、库 存、物流、服务等动态信息则通过异步调用方式填充至静态化后的页面框架内。

        缓存方式

        整体可划分为应用服务器、Web服务器、CDN节点、客户端浏览器4层缓存体系(如图3所示),分别承载不同使命。

天猫浏览型应用的CDN静态化架构演变

图3  缓存整体划分

        缓存系统方面从开发成本、稳定性、I/O性能各方面综合考虑,选择了阿里内部广泛使用的分布式key/value系统 Tair,存取静态化后的 页面。相对 Nginx本地硬盘缓存方式来说,本地Tair读写性能更优,且服务器响应时间和负载波动影响小,使用及维护成本低。整套体系详解如下:

  • 应用层缓存:减小后端应用服务器压力,减少远程调用量。
  • Web服务器缓存:减小后端应用服务器压力,抵挡瞬间峰值和/或针对少量定点内容的攻击。
  • CDN缓存:合理地利用CDN,内容缓存放置在离用户最近的地方,加快响应的速度。
  • 浏览器缓存:减少用户请求数量,降低系统压力,提升用户体验。

        缓存失效

        缓存失效主要包含“失效后台进行主动失效”和“缓存过期自动失效”两种机制。针对主动失效,主要技术难点包括以下3个方面:

  • 失效来源及监控范围:基于业务决定需要监听哪些数据源哪部分内容变更,通过变更消息接收执行缓存失效动作。
  • 每秒失效数据量级:单位时间内大量数据源(如商品、店铺装修)失效处理。
  • 要失效的缓存范围:支持批量(例如基于域名)和单个数据源缓存失效变更。

        以商品详情系统为例,失效来源主要为商品数据及店铺装修信息,后台用户修改导致对应内容发生变更时,通过消息机制通知失效后台。失效后台接收消息并保留待失效商品ID,通过调用本地Tair接口失效缓存,大致流程如图4所示。

天猫浏览型应用的CDN静态化架构演变

图4  缓存失效流程

        改造效果

        依然以天猫商品详情系统为例,采取静态化架构后,2012年双11时,在性能方面,结合后期完成的店铺装修分离等优化工作,系统单机(实体机) 在80%缓存命中率的情况下,安全QPS(每秒查询率)相较2011年同期单机性能提升7倍多,系统资源则不到原来的50%。与此同时,静态化还解决了单 URL热点攻击问题,更重要的是,使得原动态架构下依赖的后端Java系统可以转变为弱依赖:一方面既通过静态化缓存层一定程度上保护了后端系统;另一方 面在极限情况 下,当后端系统不可用时,可以通过缓存维持一部分访问量。

        第二阶段:统一Web缓存

        第一阶段以商品详情为主的静态化架构改造取得了良好的效果,除天猫商品详情系统率先完成改造外,店铺等浏览型业务系统也很快参照类似方案完成了 架构调整。在过程中,逐渐确立了静态化技术规范,简化了接入步骤;同时,也发现在各自的系统中,尽管同样基于浏览型业务场景,但由于采用的缓存方案细节差 异,存在一些涉及静态化缓存体系相关的共性问题,包括以下几点:

  • 单机缓存静态页面,受部署模式影响,缓存层无法水平扩展。
  • 单机模式下,缓存受限于服务器能力及内存容量,命中率受制约。
  • CSI模式填充动态内容,需要前端脚本配合,开发成本较高。

        因此,自然而然想到有必要统一Web缓存层接入,共享静态化集群以节省成本、提高稳定性和命中率。从运维角度看:

  • 统一接入层可以减少多个应用接入使用的成本,接入的应用只需维护自身Java系统,不用单独维护缓存;只要关心如何使用,统一的缓存框架也可更好地让更多流量型系统接入使用。
  • 统一接入层易于维护,并可统一加强全局监控、实现配置自动化,使集中维护升级更加便利。
  • 统一接入层可以共享内存,最大化利用内存,不同系统间的内存可以动态切换,有效应对攻击等类似突发情况。

        搭建统一接入层,需要针对各浏览型系统做局部改动。而整体需要重点解决的技术问题,从架构层次上看,主要涉及以下几大部分:

        缓存系统选择

        第一阶段各浏览型系统采用了单机缓存模式,基于成本、业务场景等各方面因素稍有不同。搭建统一接入层需要能够兼顾各浏览型系统的特殊要求,同时 还需能支持共 同需要的ESI解析及ESI模式下GZIP压缩,完成静态页面局部动态内容服务端填充;性能方面,能够满足双11/双12流量压力下的QPS(每秒访问 率)要求;支持失效协议以及长连接,可执行批量失效。综合以上分析,并考虑未来静态化内容最终CDN化部署方式,统一接入层Cache最终软件层面可支持 以上所有功能,同时还包括快速失效和预热能力,支持CSS和JavaScript的脚本合并,长连接和批量失效,支持基于HTTP头的可编程配置等。

        统一失效机制

        与缓存软件变更对应,各接入统一缓存的浏览型系统需针对新的缓存体系及协议改造原有失效机制,使用公共协议标准来执行批量及单个对象的主动失 效。同时,建立 了统一的失效中心和缓存校验层,所有接入应用的主动失效请求统一经由失效中心,通过Purge方式执行缓存失效。底层失效源方面,监控信息源数据变更。以 商品为例,当商品编辑完毕,包括商品标题描述等更新后详情页面需要失效,基于实时监控和消息机制进行主动失效(如图5所示)。

天猫浏览型应用的CDN静态化架构演变

图5  基于事实监控和消息机制主动失效

        Web服务器改造

        缓存层之前的Web服务层,需要能支持一致性Hash分组,并集成现有系统使用的Session框架,可支持基于域名虚拟主机的动态配置。为 此,核心系统部门的同事自行开发了淘宝定制版本的Nginx服务器(Tengine),作为统一接入层之上的Web服务器层部署。

        网络流量支持

        统一接入缓存层后,由于集中了各系统缓存信息且访问集中,所以网络部署层次方面,可使用万兆网卡配置解决硬件瓶颈;同时评估集群需支撑的网络出口流量,确保机房内部及外部出口无瓶颈;在缓存不命中的情况下,需能支撑请求回源服务器端形成的内部流量。

        整体部署方案

        图6是整体部署方案,从中可以看出:

  • 统一接入层部署,包括前端Nginx服务器+缓存系统+后端Java应用部署结构。
  • Web服务器层做一致性Hash分组。
  • 统一缓存层支持ESI或CSI方式获取动态内容。
  • 统一失效中心机制失效缓存。

天猫浏览型应用的CDN静态化架构演变

图6  整体部署方案

        改造效果

        统一接入层于2013年上半年改造完成并开始了商品详情等浏览型系统的接入工作,完成后,在原有单机缓存模式之上又增加了一层集中式缓存,解决 了缓存层的水平扩展问题。万兆网卡的使用有效解决了缓存层的网络瓶颈。由于统一接入层与应用无关,因此可以多应用共用,使监控和维护成本大大降低,并提高 了质量和效率。当然,这一改造也造成应用对缓存层的强依赖链路,同时这一层缓存也存在单点问题。从静态化单机缓存模式到统一接入层,路只走了一半,一切改 造的终极目标,是利用CDN分布式、地域性特性及强大的流量容量体系,实现浏览型应用的CDN静态化。

        第三阶段:CDN静态化

        统一接入层解决了单机缓存内存使用率低的问题,摆脱了单机缓存受内存大小制约,在面对商品数量增加和商品热点分散的场景下,只能垂直扩展那些无 法水平扩展的 问题,这提升了缓存系统的可维护性和扩展性。在完成系统从单机静态化缓存到统一接入层的架构改造之后,已经具备了将静态页面放置到CDN上的条件。CDN 提供了更强的服务能力,放置在离用户最近的节点上,是缓存系统单元化最理想的架构。同时,也为双11峰值流量和防攻击提供了更为可靠稳定的保障。

        CDN化涉及3个具体技术难点:

  • CDN分布式节点失效问题。方案:采用主动失效的方式,商品变更后主动发送请求给缓存校验层,由其通知失效中心,接收并分发处理节点失效任务,以确保秒级失效。
  • 命中率问题。方案:优化节点部署条件,CDN节点数量可控,避免失效请求量过大,靠近流量集中区域,且节点到主站网络稳定;控制节点数量,访问流量集中分布在这批节点;节点内部采用类似统一缓存层的一致性Hash规则,以达到类似命中率。
  • 局部区域动态内容定时切换。方案:价格、库存等动态信息走动态系统接口,通过异步方式获取;展现端定时切换活动Banner等内容,走ESI回源,并同样缓存回源的静态资源。

        整体架构

        基于以上思路,总体架构已经较为清晰,方案上从缓存体系、失效模式、动态内容填充几方面入手执行改造,整体架构如图7所示。

天猫浏览型应用的CDN静态化架构演变

图7  静态化整体架构

        缓存体系

        统一接入层和CDN节点上都是用Web服务器+Cache方式。静态化应用对应的域名会被解析到CDN和统一接入层的虚拟 IP上,CDN拿到请 求后,先读取 本地缓存,缓存不命中则到统一缓存层获取。统一接入层按原有逻辑处理请求,缓存不命中则回源到服务器端获取数据。同时,统一接入层Web服务器需要能够识 别用户请求是CDN回源类型,还是正常请求,以免重复打点访问日志和GZIP压缩。

        缓存失效

        缓存失效原理与统一接入层类似。失效执行流程大致为,客户端请求经VIP被随机分配给失效中心某个节点,然后失效任务被发送至代理,经代理向缓存服务器发送失效命令并返回结果,如图8所示。

天猫浏览型应用的CDN静态化架构演变

图8  缓存失效原理

        动态内容填充

        业务方面,因为存在定时切换页面局部内容的需求,整体架构中增加ESI和页面打点作为动态内容填充方式。ESI标签由Cache层负责解析回源,并且会对ESI请求做缓存,并且提供如下特性。

  • 需要定时做全站变更的页面模块用ESI的Include实现,时间判断则放在应用服务器处理回源请求的时候。
  • 回源以后,应用服务器设置失效时间。例如请求回源时应用服务器加上s-maxAge,这个页头的缓存在定点失效。
  • Cache系统提供合并回源,避免重复,防止失效后的高并发回源给应用服务器带来冲击。
  • Cache系统在ESI的缓存失效后回源,回源的请求处理期间不会挂起外部请求,会继续向客户端返回老版本的页面,回源请求处理完以后更新成新版本。类似Copy on Write,防止回源请求挂起导致前端服务器挂起。
  • ESI回源时对Response Header的操作不会发到客户端。

        改造效果

        最终基于CDN静态化的架构去除了单机缓存的横向扩展瓶颈,命中率越高、系统容量越大的特性决定了可以用较小的成本支持峰值流量;引入ESI编 程模型,解决 了页面上的局部刷新问题,支持双11业务中一些需要全网定时切换页面内容的特殊需求;静态页面+弱依赖改造带来高可用性,并最终沉淀出了一套与应用无关的 缓存和失效体系。2013年双11当天,凭借这一整套CDN静态化架构,天猫商品详情等浏览型系统平稳度过了创造历史的一天,无论是页面访问量(PV)还 是页面请求峰值(QPS)均创新高,而系统本身非常稳定,并有充足余量承受更大级别的访问流量。同时,新的部署模型和基于CDN节点地域特性的缓存体系, 也降低了秒级请求的冲击型峰值,更好地满足了系统稳定性需求。在未来一段时间内,与天猫类似的浏览型系统均能够参照这套架构体系较为方便地完成静态化改造 和接入,并达到理想的稳定性和可伸缩目标。


http://chatgpt.dhexx.cn/article/NQpQo1JB.shtml

相关文章

java 确保线程安全_确保不安全感

java 确保线程安全 33岁的克雷格斯宾塞(Craig Spencer)在治疗埃博拉病毒患者后于10月17日从非洲返回美国。 几天后,他的埃博拉病毒呈阳性React。 每个人(尤其是周围的人)和纽约人都感到关切。 纽约市市长走到媒体前&am…

经验:一个秒杀系统的设计思考

前言 秒杀大家都不陌生。自2011年首次出现以来,无论是双十一购物还是 12306 抢票,秒杀场景已随处可见。简单来说,秒杀就是在同一时刻大量请求争抢购买同一商品并完成交易的过程。 从架构视角来看,秒杀系统本质是一个高性能、高一…

Java调用C++/C

Java调用C/C有3中方式:JNI、JNA、JNative。 注:1、个人觉得还是JNA的方式最好。 2、Java和C/C交互的难点在于数据结构的对应 3、java不可以直接调用C#代码,C#代码需要托管 JNI (Android调用,普通java类似)…

kubernetes 静态存储与动态存储

静态存储 Kubernetes 同样将操作系统和 Docker 的 Volume 概念延续了下来,并且对其进一步细化。Kubernetes 将 Volume 分为持久化的 PersistentVolume 和非持久化的普通 Volume 两类。为了不与前面定义的 Volume 这个概念产生混淆,后面特指 Kubernetes …

Java多线程整理

目录 1. 进程与线程 1.1 进程 1.2 线程 1.3 并发与并行 2. 多线程 2.1 多线程的概念 2.2 多线程的好处 2.3 主线程 3. 线程的创建与启动 3.1 继承Thread类 3.2 实现Runnable接口 3.3 实现Callable接口 3.4 run方法调用和start调用的区别 4.线程的状态 4.1 线程状…

th和td标签的区别

th和td标签的区别 开发工具与关键技术: Dw HTML 作者:邹贺汗 撰写时间:2019年2月4日 在写这篇文章的时候我就知道虽然我发的不是第一个,但是说不定我写刚好给有需要的人看到了呢,所以我就写了这篇文章,下面…

html中th标签添加方法,HTML th 标签

HTML 标签 标签表示HTML表格的表头部分,该标签中的内容会以粗体显示,请参考下述示例: 实例 一个简单的 HTML 表格,带有两个表头单元格和两个数据单元格: MonthSavingsJanuary$100 尝试一下 (更多实例见页面底部) 浏览…

thymeleaf标签之th:href的使用

项目中使用springboot来进行开发,自然也就接触到了thymeleaf这套模板,如果你对c标签很熟悉的话,我觉得上手这个应该是很快的。 介绍下th:href在项目中的使用。 它的写法与th:src一样 一般写法为th:href"{值}" 如果是需要从model…

使用thymeleaf时,th:类标签失效的原因

问题出现: 最近学习后端,学到了thymeleaf这一块,学习中出现了一个问题我没有注意到,导致后面页面编写出现重大bug:项目中我使用了thymeleaf,配置的映射路由为:/index,访问首页的时候…

HTML——表头标签th的属性

<th>标签的属性和<td>标签的属性及语法格式非常的相似&#xff0c;用于设定表格中某一表头的属性。 <th>标签中常用的属性 标签描述align设置单元格内容的水平对齐方式valign设置单元格内容的垂直对齐方式bgcolor设置单元格的背景颜色background设置单元格的…

标签thead与th的区别

标签thead与th的区别 如图所示&#xff0c;thead 和 tbody标签在tr外层&#xff0c;具有更好的语义化&#xff0c;而th在 tr 之内&#xff0c;与td同级&#xff0c;起到文字加粗的效果

html中table标签、tr标签、th标签、td标签的基础知识

html中table标签、tr标签、th标签、td标签的基础知识 表格的结构表格的基本标签表格标签的基本属性table标签的基本属性tr标签的基本属性th和td标签的基本属性 表格高级样式设置相关概念外边框线样式属性frame内部边框样式属性rules 单元格合并水平方向单元格的合并垂直方向单元…

4、HTML——表格标签、表单标签

目录 一、表格标签&#xff1a;table—tr—td/th 1、合并单元格 1.1 合并同行不同列的单元格&#xff08;列合并&#xff09; 1.2 合并同列不同行的单元格&#xff08;行合并&#xff09; 二、表单标签&#xff1a;form 1、form标签 2、input输入标签 2.1 type属性…

html中的tr,td,th标签

tr是 table row 表格的行 HTML中 标签定义 HTML 表格中的行。tr 元素包含一个或多个 th 或 td 元素。 td是table data(表格数据) HTML中 标签定义 HTML 表格中的标准单元格。 元素中的文本通常是普通的左对齐文本。 th是table heading表格标题 &#xff0c;一般表格第一行的数…

javascript网页二次元3D小人详细教程

一.科班直接复制以下代码到vscode打开网页即可(小白请往下看教程) 二.小白详细教程(没有代码编译软件一样能做出来看到效果) 三.视频展示 一.科班直接复制以下代码到vscode打开网页即可(小白请往下看教程) javascript网页二次元小人(眼睛跟随鼠标移动) <!DOCTYPE html>…

web期末作业网页设计——JavaScript

目录 一.作品简介 二.网页效果 首页 花语 登录界面 注册界面 三.网页代码 首页 登录界面 注册界面 视频界面 一.作品简介 网站系统文件种类包含&#xff1a;html网页结构文件、css网页样式文件、js网页特效文件、images网页图片文件。 网页作品代码简单&#xff…

HTML+CSS+JavaScript网页特效源代码(复制代码保存即可使用)

以下下代码直接复制保存即可使用 特效一特效二特效三特效四特效五特效六特效七 特效一 方块运动演示 <html><head> <meta charset"utf-8"> <title>蓝盒子</title> <style>body { margin: 0; padding: 0;background: black…

JavaScript实现网页关灯效果

JavaScript实现网页关灯效果 案例池子&#xff1a; JS实现鼠标悬停变色 JavaScript中的排他算法实现按钮单选 JavaScript中的localStorage JavaScript中的sessionStorage JavaScript实现网页关灯效果 JavaScript实现一段时间之后关闭广告 JavaScript实现按键快速获取输入框…

JavaScript 网页购物车项目

今天是JavaScript的一个汇总&#xff0c;最近小编把自己曾经写过的JavaScript 网页购物车项目给整理了一下&#xff0c;大家可以看一下&#xff0c;然后自己也可以写一个网页购物车项目噢&#xff0c;然后我们的JavaScript的学习也到此结束啦&#xff01;下周开始给大家更新 新…

js实现网页自动化

不讲废话&#xff0c;直接主题 一、总览 二、元素获取 1、原生获取 2、jq获取 三、元素操作 $0 代表当前元素&#xff0c;下面给几个典型的例子&#xff0c;其他以此类推。 1、文本框 $0.value "United States"2、下拉框 $0.value "United States" …