Java教程

我,要把这 200 万张页面切出来上线

本文主要是介绍我,要把这 200 万张页面切出来上线,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

前端早早聊大会,前端成长新起点,帮你提前二十天,站在新的起跑线,目标成为用得上,听得懂,抄得走的前端大会,计划 2020 年办 12 期,由前端早早聊与掘金联合举办。

第五届 - 前端监控体系如何搭建/用户行为/产品质量如何跟踪,报名链接:huodongxing.com/go/tl5

本篇为第三届 - 前端页面搭建专场奕纯讲师的分享:


大家好,下面我介绍下阿里妈妈营销和体验中心前端团队的搭建平台。
目前而言,搭建平台有很多实现方案,有面向 B 类用户进度低代码搭建,大概就是从非常基础的组件开始,例如按钮、下拉框之类的,组合形成一个完整的页面,这类页面的样式往往比较标准,而功能又很比较复杂,有时候可能也还得介入下开发点代码,比较适合搭建内部工作平台或者页面,阿里这边有诸如宜搭这类的,相信在前面有同学进行了详细介绍。
还有一种面向 C 类用户的,也就是搭建面向普通消费者的营销页面,这类页面样式往往比较绚丽,而功能相对比较单一一点,基于的基础物料往往都是完成度比较高的业务组件或者直接就是一个可配置页面,并且可以由非技术类同学进行简单配置即可进行业务定制发布,从而达到整体业务效率提升。
阿里妈妈营销搭建平台属于后者,目前包括搭建端和渲染端都是基于 Node 实现的,当然相信关于搭建的其他方案前面的同学已经说的详细了,我这边也是为了形成话题的差异性,大家着重探讨下搭建平台往往会面对的一个后勤保障问题——即物料推送部署。

个人介绍


先自我介绍下,花名奕纯,目前在阿里妈妈前端创意团队,负责搭建体系的基础建设。大概在 16 年初的时候加入阿里妈妈前端团队的,负责在业务团队内对接搭建方向的一些解决方案。
额外提及一下的是,之前在百度那边负责物流调度平台的开发,为什么要额外提下呢?因为今天主要讲解的部署推送模块和物流系统也那么一丢丢的关系,从概念上都是货物运输,大家可以先想象下,具体内容接下来慢慢和大家展开。


这里是今天的分享大纲,主要分三个部分最后稍微总结下,当然在进入主要话题之前,在第一部分和第二部分我给大家简单介绍我们的产品架构和搭建方案,第三部分进入本次的主题,来和大家探讨下分析和设计一套可支持大规模物料的部署方案。

搭建产品架构介绍



先介绍下我们的产品架构。
先来介绍下我们的部门,相信很多同学对阿里妈妈有一定的了解,我们主要就是负责阿里集团的广告营收的部门,说到互联网广告自然避免不了广告制作和投放。
最初的做搭建平台的原始需求是广告主们处于宣传的目的需要制作广告创意落地页,然后进行投放。这里广告创意的制作有一定的门槛,广告主又不太可能让让他们都进行页面开发,所以页面搭建平台可以帮他们完成这个目标。
从广告页面形态上那自然是 H5 页面比较适合进行投放,所以阿里妈妈这边很早之前就开始尝试进行搭建平台的一些建设,主要用于服务于广大的广告主进行页面搭建。做为搭建技术其实也同样可以用于面向内部小二的营销搭建平台,当然内容管理平台属于维度更低的一级,有业务需求支持一下在技术上也是天然支持的。

产品架构简介



这里是我们的整体产品架构简图。
淘积木平台就是面向广告主的广告创意落地页的搭建平台,ALP是我们面向内部小二的一个营销页面搭建平台,它全名为 Alimama Landing Platform ,它也有个别称叫做爱老婆平台,当然这两个平台除了业务支持上有所差异,底层的搭建方案整体都是一致的。
另外两个是偏向技术,接口编排主要是面向数据接口进行可视化配置的,可以理解成数据方面的UI层,但是可以支持可视化编排的;工程套件主要是让内部开发小二进行基础物料制作的工具,也就是一套基于命令行的开发工具。
当然我们前端团队这边还有其他明星级的产品,也有力的支撑和强化了我们的整体搭建能力,例如用于图文和视频渲染的创意中心平台、用户矢量字体的管理的 iconfont,这些主要都是基于 Node 来实现的,Magix 是我们自己开发的一个前端框架,类似于 React/Vue,在日常开发中都很好的融入到了我们的搭建平台上。

产品价值总结


这里是我们的搭建平台一些数据情况,目前总共服务 30w+ 广告主用户,在内部也全面覆盖到阿里妈妈的各个业务中,搭建的页面总量目前已经突破 200W 个,并且还在以极快的速度增长,每天承接 3 亿多次 PV,当然大促期间请求量会更大,而且这些都是基于 Node 实现的,在阿里集团内部算是一个非常大型的 Node 服务集群了。
从产品价值而言,不仅仅让广大的广告主更加容易的创建广告落地页,在内部也帮助我们极大的提升了整体业务效率,很多页面从制作到发布不再需要开发介入。举个例子,之前我们某次大促,光内部这块活跃的营销活动页就上千个,而且随着促销策略变更都需要进行发布推送操作,如果没有搭建平台的帮助,依靠有限的开发资源基本是不可能完成的,所以不仅解放了开发的生产力,也让业务迭代效率更高。

搭建解决方案介绍


接下来从搭建方案的角度带大家一起看看,其实看了很多搭建的实现方案,如果只看搭建方案的实现结果,都是有一定的相似性的,在实现细节和技术方案部分都各有千秋。
对我阿里妈妈这边的搭建平台而言,我们的内部其实也将整个体系叫做乐高 2,其含义就是像乐高堆积木一样的来完成页面搭建,这个名称其实和集团的那个乐高有点冲突,但是并不是基于集团的乐高而命名的,其实阿里妈妈最初在探索搭建方案时也叫乐高,后来升级换代后就叫做乐高 2,不妨碍我们看出其最初的产品设计思想,就是像搭建积木一样的来搭建页面,淘积木平台也是基于这个来命名的。

搭建的基本概念



所以,我们的搭建方案是将基础物料,诸如组件看作积木零件,搭建完成的页面看作是积木成品,通过这个比喻大家应该能够想象我们的基本方案,其实和大家的搭建方案可能也是类似的。
我们的搭建平台主要的基础物料就是组件,具体的我们进一步分类成了母板组件、布局组件和业务组件,他们在功能上有所差异,但是在技术处理上是基本一致的。

  1. 业务组件,比较容易理解,就是直接组成页面不同区域的可复用的业务逻辑单元
  2. 布局组件,就是约束业务组件具体展示位置的一种特殊组件
  3. 母板组件,其实就是页面的执行上下文容器,比如在这里声明页面依赖的具体静态资源等等


当然也包括一些其他的和搭建弱相关的物料,例如用于 ABTest 的分流、用于支持可复用代码片段的区块等。
这是我们的搭建界面,基本上大家的在这里的实现都有点类似,左侧是页面搭建的预览区域,中间是组件树信息,右侧是非常重要的运营数据编辑区域。

运营视角下的搭建流程



搭建的大致过程,首先你得选择一个母板组件,做为容器来承载其他的业务组件,母板组件的配置是开放的,基本上每个业务线会开发一套自己使用的母板,然后业务线的搭建者一起使用,具体母板组件的实现如何又各个业务线自己自由开发。
完成母板选择后,执行容器就建立了,然后从组件仓库里挑选合适的组件添加到页面即可,这里有个小视频展示一下,基本步骤就是:

  1. 用户添加组件
  2. 调整组件位置
  3. 配置组件的运营数据
  4. 完成验证后保存发布


如果无需加入组件,直接从第三步配置组件的运营数据开始即可。
从运营搭建视角而言,实际上搭建流程也是比较简单小白的,这里的搭建方案的核心物料就是形形色色的组件,并且组件是可复用的,例如如上的商品卡片组件可以在很多页面部分使用,也可以通过配置组件参数来改变组件的展现。

开发视角下的开发流程



从开发视角而言,还需要关注物料的生产过程,借助工程套件实现基础物料的开发,整个搭建流程如上,基础物料的制作、开发、调试和发布都是在本地命令行中进行的,完成后发布到搭建平台的存储中,有了现成的物料,再由运营或者开发同学借助可视化搭建平台进行页面的生产,或者由运营进行直接搭建和配置,完成的页面最后推送到我们的渲染集群。
这里解释下渲染分为集中渲染和独立渲染,大家可以简单理解成将不容的业务的内容分发到不同集群进行渲染处理,从而避免将鸡蛋放入到一个篮子里隔离风险,当然具体分发过程也是基于部署模块来推送的。

技术原理和架构



从技术架构视角来看,左侧这个大图是我们的大致的技术架构图,按照不同功能层级进行划分

  1. 搭建层主要负责物料和页面的生产;

  2. 存储层将生产好的物料及其信息存储下来,后面再由渲染层进行调度消费;

  3. 渲染层主要就是基于页面的配置信息,将物料组合成完整的页面返回,这里有我们核心的一些功能模块组成,例如渲染引擎、分流模块之类的了;

  4. 应用层,除了调度渲染任务之外,也会处理一些额外UI层逻辑,例如一些数据代理、验权问题、缓存配置等等;

  5. 独立集群,之前也提及过,主要就是分担风险,比如联盟那边有些很重要的页面,挂了会对直接影响交易大盘的,往往会独立建立一个集群专门进行渲染;

  6. 静态资源主要是托管基础物料等的资源文件,主要及时脚本、样式和图片等静态资源等等;

  7. 我们应用层也会作为 CDN 的源站,另一方面我们也有很大比例的实时页面渲染请求,实时渲染也会增加业务的灵活性,比如 ABTest 的场景往往得用实时渲染来完成;

  8. 接入层,主要就是面向用户的一些请求入口;
    那么,右下架我们把整个架构图极度精简下,也就是生产、运输和消费,其中运输也就是我们今天要讨论的部署问题,可以将其看作一个后勤保障问题,那么我们接下来重点阐述下部署模块。

海量物料部署方案


首先,为什么会有部署问题,直接将页面和组件静态资源上传的 CDN 上,然后前端引入不就可以了吗?确实是一种方法;不过,阿里妈妈这边的搭建服务场景和需求比这个复杂很多,后端实时渲染页面占了很大比例,并且很多接口数据是动态的,并在服务端渲染从而满足首屏直出的一些性能优化的一些需求,另外发布生效的实时性也是要考虑的,还有诸如 ABTest 实验等等;基本上,从业务发展和技术角度而言,强有力的部署模块提供了更多的可能性。
就我们业务的现状角度而言,首先可以看到规模很庞大,目前已经有 200W+ 个页面;而且,每个月会新增大量业务,如果业务再持续增长,可能增长还要更加快速。
想象一下,整体物料增长规模增长到一定级别后,部署系统无法支撑,需要重新改造,然后要解决几百万上千万个页面的数据迁移和验证问题,所以这个针对物料运输的后勤保障问题长远来看其实也是比较关键的。
下面我们先从分析部署模块面对的问题,然后介绍下我们部署模块的演化过程,最后探讨下实现一个海量物料部署方案。

部署模块要面对的核心问题



先来分析部署模块面对的问题,当然主要问题就是能够实现物料推送,如果这个都实现不了那就算不上部署了,除此之外大体上我列出了其他核心问题:
规模膨胀,一般搭建平台都是需要长时间运行的,规模膨胀问题也许不可避免,由各种因素使得其成为不得不考虑的问题,毕竟业务增长和需求总是不可预估的,避免未来被基础设施限制,是需要考虑的;
集群部署,这里主要指一些运维和集群配置问题,如何在服务机器集群上进行物料管理,集中到单一集群如何保障重点业务的稳定,单一业务的冲击如何保障不对其他业务产生影响,集群扩容等运维操作如何让海量物料也跟随者一起走等等;
稳定保障,各种日常开发引入的 bug 导致部署推送出现问题时,如何避免产生灾难性后果;依赖的存储等服务挂了,集群是否还能提供服务;
安全防护,如何避免非法请求对系统的冲击等等
当然,部署面对的问题还有很多,我们从这几个典型问题出发来进一步探讨一下。

可用的基础工具



那么在正式开始之前,我们要完成一个部署模块的开发,有哪些工具可用呢?
第一,涉及到消息触达的,基本上有消息中间件,阿里这边主要用的 metaq,它能保障消息的顺序触发;另一个实际上是配置发布工具,阿里这边是 diamond,发布后会通知所有的订阅的集群。二者概念上还有点差异的,行为上也会有所不同,metaq 是消息中间件,自然擅长消息处理,diamond 只是一个配置发布工具,没有消息队列之类的概念但是有存储能力,但是他们都能进行消息触达。
第二,持久化,例如 redis,tair 也是一个类似于 redis 的一个 nosql 的存储,mysql 也算是一种可用的选项。还有一个就是文件存储服务,阿里这边主要是 oss。
第三,从代码实现来看这边,基于 Node 的 egg 是个不错的基础框架,它的插件生态涵盖了所有这些工具,而且也很容易的自己实现一些插件;还有其进程机制,也就是一个 Agent 进程和多个 Worker 进程的模式,也可以在进程之间进行通信等等。

部署模块演化情况



那么,基于这些基础工具,结合我们这边的部署方案的演化来一起层层递进的解析部署的解决方案,大体上而言阿里妈妈的部署解决方案经历了三个阶段的发展:

  1. 最简单和最原始的推送和下载
  2. 面向小规模的文件同步方案
  3. 以及最终的海量物料部署方案


下面我们详细来看看

最早的推送和下载方案


很久之前我们实现两个一套简单而粗暴的部署方法,那时候 Docker 容器技术还未普及,egg 也还在酝酿开发之中。
这个部署实现可以用一句话描述:搭建平台发布 metaq 广播消息,渲染集群接受到消息后,再通知渲染的进程去文件存储服务上进行文件下载。简单而粗暴的解决了一个部署问题,然而有哪些问题呢?

  1. 那个时候,我们要进行系统扩容,只能将物料目录打包,然后转存起来,扩容机器后,再下载到机器上进行解压,然后再进行自己验证,验证过程主要上是通过流量回放的方式进行。
  2. 后来集团开始推 Docker 虚拟容器技术,日常上线也成了问题,因为 Docker 每次的部署类似于重装系统,磁盘也基本重新更新了,当然实际要轻量级很多,好在借助 Docker 的 Volume 挂载了一个目录暂时解决了这个问题。


基本上,这个时候,除了解决部署推送问题,其他的主要问题都未解决,我们来逐一对照一下:

  1. 规模膨胀,很显然没有相关概念,基本都是通过磁盘来存储的,而且随着规模逐步增大问题也会越来越严重;
  2. 集群部署,上面也说了,基本都是人肉解决;
  3. 稳定保障,也基本没有稳定性概念,文件丢失或者其他故障,基本这个页面的请求也就废了等。
  4. 安全防护,对于非法请求,也没有相应方案。


所以,整体而言这个简单粗暴的方案,解决了最基础的部署推送问题,除此之外无其他特征,不过这是早期的方案也是可以理解的。

小规模的文件同步方案



这个也是在较早之前,业务方希望我们能够更好的保护重点业务和其他业务在物理层面上隔离,也就是害怕集中渲染中不确定性因素导致重点业务被影响到;这些重点业务的一个特质就是页面总量不大,针对这个需求我们也就开发出了一套适用于小规模页面的文件同步方案。
基本执行原理就是在部署时:

  1. 在搭建端,在每次部署发布时,将变更的页面存储到 OSS 上,并生成一份全量的文件信息表,通过配置发布工具 diamond 进行发布;
  2. 在渲染端,Agent 进程接受到了 diamond 的消息通知,然后拉取此次变更的文件信息,然后经过一系列复杂的计算,获取到本次变更的具体页面信息,然后从 OSS 上下载部署到本地;
  3. 完成部署后,再通过 IPC 通道,也就是进程间通信,告知渲染进程进行本地缓存更新;


另外,当机器重启或者进行部署推送时,会重新从 diamond 上拉取全量的文件信息表,进行一次全量部署,完成之后再启动流量接入,由于页面规模是百级的,基本上全量部署速度也非常快,应用上线重启都和流畅。
在这个方案里,我们也实现了一套基础的容灾机制;大体原理是,在执行一次部署前,先将上一次部署的页面内容写入到磁盘的一个备份目录里,这样如果部署过程出现了问题,渲染进程还是会去备份目录里读取上一次的页面然后再进行渲染。
那么,这个方案解决了哪些问题呢?

  1. 规模膨胀,未解决,这个方案只适用于几百到千级的页面,因为变更推送后的变更信息提取以及每次应用启动时的全量部署都不允许进行大规模的处理;
  2. 集群部署,解决,正常的集群运维操作都不再需要人肉处理,而且这个方案可定向推送到特定的集群上,为业务发展也带来了灵活性;
  3. 稳定保障,解决,初步的容灾降级机制一定程度上保护了意外的故障导致的页面不可访问的问题,另外这个方案中的页面变更计算甚至还实现了灰度部署;
  4. 安全防护,未解决,如果是非法请求,基本上还要额外进行容灾处理,甚至比之前的最早的那个方案还多了一步流程。


这个方案完成开发后,也为我们积累了一定的经验,其中诸如容灾的设计理念对后面的最终方案产生了不少启示作用。

海量物料部署最终方案



后来,为了保障业务的长远发展,我们决定还是要实现一套完整而可靠的海量部署推送模块,解决我们搭建平台的后勤问题。
基本要求总结一下,部署推送是基本功能,此外:

  1. 物料存储到 OSS 上,并且一个物料有可能存在多个历史发布版本;
  2. 需要实现按需部署,当量级过大时,且机器本地上无对应物料时,按照需要进行部署;
  3. 要有容灾降级能力;
  4. 要有安全防护能力;

#### 建立基本的物料部署模型


要解决这个问题可以先尝试构建基本的模型概念:

  1. 路由表,物料的 OSS 地址查询表,可以依据物料的属性按需查询物料文件的具体存储地址;
  2. 热部署,部署的按需触发机制,当需要一个物料时动态实现部署执行动作。
  3. 冷部署,部署的主动触发机制,也就是传统的推送和部署模式;
  4. 容灾降级,在部署层面上也要提供容灾降级的能力,最低限度的提供服务,但是服务尽可能的不能挂;
  5. 黑名单,在部署层面的非法请求进来时,可以进行基础防护,避免不必要的资源消耗,特别是在有热部署和容灾机制的情况下,因为他俩的执行其实是有点耗资源的;

具体的部署方案解析



在这些基本概念设计下,实现了如上图的一个部署方案,这其中有五条故事线:
第一条线就是,搭建端,负责生产和部署推送

  1. 当完成一次物料搭建,搭建端直接将物料存储到到 OSS 上;
  2. 依据物料信息的一些计算一些特征值,并将特征值和 OSS 的文件地址的映射关系存储到一个路由表里;
  3. 将部署消息通过消息中间件传达到渲染端的 Agent 进程中。


第二条线就是,渲染端的冷部署

  1. Agent 进程接受到部署消息,依据物料信息计算一些特征值,再去路由表里查询物料的 OSS 地址;
  2. 查询到 OSS 地址后,将物料拉取并部署物料到本地磁盘上,形成磁盘缓存,同时也生成一些容灾备份;
  3. 完成文件处理后,再通过 IPC 通道告知渲染进程存在部署变更;
  4. 渲染进程接受到通知,从本地磁盘读取最新的物料,并更新到自己的内存缓存中,从而完成一次冷部署更新;


第三条线,渲染端的热部署,有外部请求触发的部署动作

  1. 当外部请求进入时,依据请求信息尝试从内存缓存和磁盘缓存中获取,如果都未命中则尝试进行热部署动作,也就是按需部署的概念;
  2. 依据请求的信息计算出本次请求的物料特征值,再去路由表里查询物料的 OSS 地址;
  3. 获取到物料的 OSS 地址,并由渲染进程发起热部署动作,并更新本地内存和磁盘缓存,以及容灾备份等;


第四条线,黑名单拦截

  1. 当一个请求是非法的,执行热部署,还有容灾降级很显然是不会成功的;
  2. 那么在完成一次失败的热部署后,将请求的特征进行拉黑;
  3. 当下次同样的非法请求进来之后,可以直接实施拦截,避免无必要的热部署动作等;
  4. 那么如果有冷部署执行了,还是会更新一下黑名单里的特征值,为什么要更新呢?因为一个页面在初始未发布前如果进行了大量请求,由于找不到这个页面,这时其实是会被拉黑的,但是当执行发布了,相关的请求有变的合法了,所以需要更新下黑名单列表;


第五条线,容灾降级基本原理如下

  1. Bug 往往不可避免,例如 JSON 格式错误等,可能会导致一个页面无法完成渲染,如果恰好这个页面很重要往往容易悲剧。
  2. 容灾降级会提供尽可能的服务,因为上一次部署的页面大概率是可以正常渲染的,容灾模块模块会尝试在正常流程失败时获取上次的部署结果来进行渲染;


所以,这个方案解决了所有提出的问题。

  1. 规模膨胀:海量物料的存储通过内存缓存、本次磁盘、以及路由表和文件存储等,基本上是线性增长的,按目前的存储容量支持亿级别的物料总量也没什么问题;
  2. 集群部署:冷热部署模式都可以看作是按需部署,基本上物料也随着集群走,日常集群运维完全不用担心,另外依据物料的特性也很容易实现定向集群推送的部署;
  3. 稳定保障:部署层面的容灾机制可以确保最大可能的提供服务,为修复故障争取时间,当然包括渲染等也会有其他层面的容灾机制;
  4. 安全防护:黑名单机制也可以有效屏蔽非法请求,保护机器集群的稳定性;

类比现实时间的物流仓储管理系统


整个看上去略复杂,然而实际上你会发现,整个部署方案其实就是一个类似仓储和物流系统,正好我之前也做过物流平台的管理和开发。这里稍做解释下:

  1. 冷部署,其实就是工厂生产以及货物运输过程,当货物到达超市的仓库时,仓库管理员也就是 Agent 进程将货物进行分发管理;
  2. 请求响应,当顾客进入超时购物时,按需根据商品类目去不同的货架上查找需要的商品,而货架也就类似于我们的内存缓存,本地仓库就是本地磁盘缓存,远程仓库也就是路由和文件的远程存储;
  3. 热部署,顾客在货架上找不到所需商品时,货架管理员或者售卖员,也就是热部署模块,会去仓库里调度货源,并进行上架。
  4. 黑名单拦截,如果顾客进店一直要寻找奇奇怪怪的东西,感觉充满了恶意,则触发保安系统,当同样的顾客下次来时,直接拒绝他进入。
  5. 黑名单更新,也许顾客比较超前,想买还未生产的商品,此时已经对他进行拉黑了,当冷部署将最新的商品送到时,则更新安保系统,下次顾客进店时则直接放行。


这样类比一下是不是很容易理解了,其实最初我们不是对照着物流系统去完成的部署模块设计,而是完成部署设计并实现后发现其很类似于物流系统,应该说并不是巧合。

部署方案的线上执行情况



下面我们来看看这套部署系统在我们线上的的执行情况。
左上角,可以看到路径黑名单的拦截情况,很多是攻击类的请求基本上都是持续不断的。
右上角,是页面的黑名单拦截,可以这个图里看到突然有了大量的非法请求进入,被黑名单模块通通了拦截。
下面那个是容灾执行情况,日常情况都是一些非法非法请求导致的,容灾也是比较耗资源的,这里也可以看出黑名单拦截的价值。


这里展示的是一次系统上线时,内存缓存的填充过程。
上图是内存的缓存由于在填充导致曲线一直在上扬,下图那个是内存缓存同时间段填入的具体操作,中间那个小图是同时间端的获取时间消耗平均情况,包括热部署、内存读取、磁盘读取等。
这里稍微解释下,蓝色曲线是 ABTest 平均的读取耗时,基本在 0.3ms 以内,黄色曲线是页面的平均读取的耗时,在 0.5ms 以内,单次的热部署耗时其实不少,但是平均下载其实延时是很低的,基本占比整个页面渲染时间来看,部署模块的物料读取耗时可以忽略不计。

上线后遇到的问题



当然,在完成开发上线时我们也遇到了些问题,这里列举两个和 Node 直接相关的。
第一个是,首版上线完大概三四天后,都会突然线上不少机器的 CPU 被打满,然后重启机器就恢复了,之后再过个几天的又会出现同样的问题。
当时排查了不少执行逻辑没找到问题,然后观察系统指标,发现每当一个机器大量进程内存占比为整体的 1.2% 的样子时会出现这个问题,我们用的是 32 核的机器,所以大概整体内存的 35% 的样子,直觉上猜到可能和内存使用有关。
最终发现问题是,当时已经日页面活跃的个数分配了一个比较大的内存缓存,在物料的填充过程中,达到了 Node 进行强制垃圾回收的阈值,从而触发了 Full-GC 问题,修复是将内存缓存设置小一点再发布,之后问题就消失了。
当然缩小了内存尺寸,对整体获取耗时略有影响,基本增长都在 0.1ms 以内,所以整体也没啥问题。
当然,后来发现 alinode 平台也有优秀的 GC 问题分析工具,由于时间有点久了,原始素材找不到了,左下方的图是另一个实例的 GC 情况基本也和内存使用有关,作为示例展示下。
第二个问题,也是首版上线后,执行一段时间突然出现大量的 Node 进程退出,并产生出了很多 Core 文件,分析下基本没有用信息,查看日志的错误栈也没啥有用信息;暂且下重启问题机器,但是运行一段时间又会概率性的出现,概率性的问题还是不好处理的。
仔细查看了下日志,怀疑是使用 IPC 传输大文件导致的,猜测是可能大文件的传输占用了内置 stream 对象的内存空间,导致 Node 执行一些操作是进程直接中断,因为最初的实现版是通过 IPC 来传输最新的物料。
紧急改造成通过磁盘转存一下物料,IPC 通知渲染进程去本地磁盘来读取最新的物料,完成改造上线后这个问题也消失了。

一些实际的执行案例列举


下面说几个线上运行案例,设计了这么多的机制是不是真的有用,还是过度设计。

容灾案例




首先第一个是容灾生效的案例,这个实际运行案例是由于部署模块的一个 Bug 导致渲染时无法正常获取到页面配置,在上线过程中发现突然收到不少容灾触发的报警,但是打开页面都是没问题的,因为是触发了降级,用了上一次的页面配置进行了渲染,排查了下发现部署执行有点问题,然后紧急修复再上线。

这个案例比较有趣的是,虽然不少服务器确实挂了,但是除了几个开发接到了报警通知,其他人完全感知不到,基本都没发现有问题,要不然这次有可能是个大故障,因为这是一个独立的渲染集群,承载重点业务用的。

拦截案例


111.001.jpeg

这个案例是在某年大促前夕,基本都是封网状态了,要知道此时发布内容和执行线上变更是很困难的,就在这个时候突然收到了大量的非法请求,触发了黑名单拦截的报警通知,黑名单模块成功识别这些非法请求并实施拦截。

所以,最终效果是,虽然被接受到了很多不明请求,但是除了收到报警通知外,整个渲染集群运行的都非常平稳,系统参数上也毫无波澜。

拓展案例


同样,部署方案也是可扩展的,可以依据物料特性进行定向渲染集群推送,我们用它替代了之前开发的针对小规模页面的独立渲染集群的部署方案,毕竟能够支持海量物料的部署,对小规模的页面也自然不在话下,目前完全支持了所有的独立的专用渲染集群的部署任务。

总结


最终总结下,如之前说的,部署模块其实就是搭建体系的后勤保障问题,整个实现方案和实际生活中的物料和仓储管理有着很高的相似性,只能说事物之间冥冥之中往往也是有联系的。

解决了后勤保障问题,我们的搭建团队在这里也就没有了顾虑,可以专注于其他搭建的方案设计和开发。

广告时间




最后广告时间,我们是阿里妈妈营销研究和体验中心的创意前端团队,团队人虽然不多但是却有着众多重量级的明显产品,基于 JS 我们完成了很多不可思议的事情!而且,我们也是阿里集团的营收部门,我们正在招人,Base 可在北京和杭州!

如果想要一起来搞事情的可以联系我!




这篇关于我,要把这 200 万张页面切出来上线的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!