2021年前端部署的灵魂拷问 前端lint

2021年前端部署的灵魂拷问鉴于页面(index.html)会频繁更新,而静态资源则相对稳定。所以,我们能推断出的一种缓存策略是 index.html 适合走协商缓存,相

考虑到页面(index.html)更新频繁,静态资源相对稳定。因此,一种可能的缓存策略是index.html适合协商缓存,相对稳定且不经常更新的静态资源(JS、CSS、IMAGES)消除了协商请求并需要强缓存,这意味着您需要使用.

但问题很快就出现了。浏览器不允许发送请求,但是如果你想更新foo.css 怎么办?

您是否希望您的缓存设置得尽可能长并随时刷新?

你想让你的马在没有草的情况下奔跑吗?

我想大家立刻就想到了给资源添加版本号的想法。比如通过查询添加版本号,每次上线就更改版本号。本例中的HTML 如下所示。

注意,此时服务器中只有一个foo.css 文件。

一刀切地添加版本号的好处是简单、粗暴、快速,但缺点是如果只想更新foo.css,bar.css缓存也会失效,浪费带宽。发生的事情。

任何人都可以很快想出一种方法,将文件的内容与版本号(URL)绑定,并且只有在文件内容发生变化时才更改版本号(URL),从而确保实现对每个文件的精确缓存控制。

它与文件的内容有什么关系?消息摘要算法[2]获取有关文件的摘要信息。这些摘要信息与文件内容一一对应,并且有一个可以精确容纳单文件粒度的缓存控制基础设施。然后将URL 更改为包含文件摘要信息的URL。

这种方法可以称为查询哈希。当后续版本上线时,仅更新已更改的文件的URL,从而提供精确的缓存控制。

注意,此时服务器中只有一个foo.css 文件。

重叠发布引起的问题

然而,如果您遵循上述部署计划并将其上线,致命的威胁很快就会无处不在,并且每次更新上线时都可能发生灾难。

让我们来看看。该网站只有一个静态文件,位于Nginx 服务器上的某个目录中。通过查询哈希在每个文件的基础上实现精确的缓存控制。有什么问题?

如果确认,更新期间foo.css 样式将发生变化,HTML 中的foo.css URL 将更新为最新的哈希值,并且foo.css Index.html 文件将保存在服务器上。由于是用最新版本(V2版本)覆盖的,看来HTML和静态资源也相应更新,但没有考虑极端情况。那是:

首先部署静态资源。在部署期间访问时,V1 版本的HTML 似乎访问新静态资源的V2 版本,并根据V1 哈希进行缓存。

首先部署HTML。在部署期间访问时,V2 版本的HTML 会访问V1 版本中的旧静态资源,并根据V2 哈希对其进行缓存。

下图展示了不同版本的HTML 和不同版本的静态资源匹配时出现的异常情况。

图片.png

绿色方向:正常访问和缓存建立路径。

红色趋势:静态资源(V2)先部署,V1-HTML访问并缓存V2静态资源。

黑色趋势:先部署HTML(V2)时,V2-HTML访问V1资源和缓存

问题1 有两个子情况。

用户本地有缓存,此时可以正常访问,没有任何影响。

如果用户没有本地缓存,则根据V1版本的hash加载V2版本的静态资源并缓存。用户报告了一个错误。 V2版本的HTML部署后,当用户再次访问时,HTML会恢复。

对于问题2,严重的可能有以下几种情况:

V2版本的HTML根据V2版本的哈希来缓存V1版本的静态资源。这时,页面会收到错误,并会继续这样做,直到缓存过期。直到用户手动清除缓存,缓存过期,或者将来发布V3版本来更新静态资源的版本。否则,用户将继续犯错误。

上述方案的问题源于静态资源只有一份,而且每次发布都是叠加的方式发布,导致页面与静态资源不匹配。这个问题的解决办法也很简单。使用非覆盖发布。一种简单的转换方法是将文件的摘要(哈希)放入URL 中。即,将查询哈希更改为名称哈希。

本例中的HTML 如下所示。

这样,每次部署时,都可以先全面部署静态资源,然后再灰度部署页面,彻底解决缓存问题。

此时,服务器上已有多个foo.[$hash].css 文件。

与CDN 集成

欢迎转载。请注明来自Byte Architecture Front End [3] 的文章。

我目前正在网上部署一个网站,但是我仍然将静态资源部署到Nginx服务器目录中,因此随着时间的推移,文件慢慢增长并慢慢淹没我的硬盘。此外,由于文件存储在Nginx Web服务器内的目录中,因此不可能使用CDN技术,因为Nginx、网站和部署过程是深度耦合的。

CDN是部署在应用层的内容分发网络,采用智能分发技术,根据用户访问的位置,按照就近访问的原则进行信息分发,实现多点负载均衡。基于

简单来说,就是让用户访问更近、访问速度更快。大型企业无需搭建超带宽存储服务器,只需使用多个常规带宽的CDN节点即可。

典型的CDN 实现具有一个源服务器和多个从源服务器定期同步的CDN 节点。

那么如何将CDN 与Nginx 这样的Web 服务器结合起来呢?

答案是将静态资源部署到CDN上,并将Nginx上的流量引导到CDN上。这项技术称为“反向代理”。

目前,用户访问研发、构建、部署流程的流程大致如下:

至此,整个部署方案需要分三步进一步修改。

构建时,根据环境变量将HTML中的静态资源地址附加到CDN域名中。

构建完成后,将静态资源上传到CDN。

配置Nginx 的反向代理以将静态资源流量转发到您的CDN。

其中,第1 项和第2 项涉及调整构建过程,以Webpack 为例,需要进行以下配置更改:

a. 将输出配置为content-hashpublicPath。

b. 配置Webpack-HTML-Plugin

下面显示了一个示例配置。

图片.png

//webpack.config.js

constCDN_HOST=process.env.CDN_HOST;//CDN域名

constCDN_PATH=process.env.CDN_PATH;//CDN路径

constENV=process.env.ENV;//当前环境等

constVERSION=process.env.VERSION;//当前发布的版本

constgetPublicPath=()={

//这里代码

根据return${CDN_HOST}/${CDN_PATH}/${ENV}/;//ENV等动态构造publicPath

}

constpublicPath=process.env.NODE_ENV===‘生产’?getPublicPath():‘.’;

模块.导出={

输出:{

文件名: \”Bundle.[名称][内容哈希:8].js\”,

公共通行证,

},

插件:[

newHtmlWebpackPlugin()

]

}

注1:您经常将一组代码部署到多个前端环境。还需要在构建过程中注入当前部署相关的环境变量(staging、prod、dev、pre等)来动态构建publicPath。

现在我们考虑了静态资源组织的解决方案。现在,我将解释一下构建流程。每次构建时都需要执行以下步骤:

拉取远程仓库

切换到XX分支

代码安全检查(可选)、单元测试等

安装npm/yarn 依赖项

设置节点版本

设置npm/yarn 源

安装依赖项等

运行编译构建

产品检验(为保证产品质量,不强制检查包装后JS文件/图片大小以及产品安全等)

手动堆点(可选,领导同意即可继续)

打包上传到CDN

自动化测试(可选,e2e)

完成剩余步骤

构建完成后通知我

其中包括即将出现的问题,例如:

构建将在什么环境中运行?

如何保证每次的部署环境都是一样的?

谁触发构建?

如何管理上述上传CDN密钥(不增加成本、保证安全、保证构建上传的可靠性)?

如何自动触发构建并自动执行上述步骤?

如果您每次都手动运行它,则可能会在发布日出现编译和打包延迟,并且更有可能遇到诸如缺少步骤或顺序错误之类的问题。

如何提高构建速度?

如何通知研发学生施工已完成?

有没有灵魂的折磨?

针对上述问题,业界有多种解决方案。

确保环境一致性:Docker[9]

按流程构建:Jenkins[10]

自动构建触发器:Gitlab webhook[11] 通知

开始构建通知:开放账户系统+依赖Gitlab webhooks

施工完成通知:家属账户系统开通

业界粗略的实现方式一般是Jenkins + Docker + GitlabWebHook。实践的例子包括:

前端项目自动部署超详细教程——(Jenkins、Github Actions)[12]

iDeploy – 为前端团队开发的持续交付平台,用于构建和部署工程[13]

我现在还有其他几个问题。

例如,宇宙中最重的物质node_modules安装是否太慢?

如何提高构建速度

上述情况在拥有比较丰富的系统解决方案的大公司中经常见到。每个公司都不同,但由于它们相似,因此我们将在本文中跳过这一步。

前端发布服务——预发布环境、版本控制(二级回滚)、小流量、灰度、AB测试

=====================================

在组织静态资源、自动化构建和部署以及配置Nginx 反向代理之后,您的网站首次上线。

但是如果你想第二次或者第三次上线呢?直接发送到生产进行回归测试的风险非常高,但是你可以在本地部署你的前端测试环境并且无法连接到。最终生产库(想想为什么)。因此,预发布(pre-)环境。只有测试人员才能访问它。除此之外,其他方面都与生产环境相匹配。

至此,第一个需求,预发布环境功能已经满足。

如果某个功能在元旦午夜发布,那么它会在除夕期间在服务器前发布吗?如果因为npm获取不到依赖而导致构建失败,或者上线后发现bug,那你就别无选择,只能放手了。

或者,随着时间的推移,随着大家的前端项目积累越来越多,node_module的质量逐渐超过星系的总质量,构建时间往往会超过20分钟。有一天,我们发布新功能时,发现了致命的阻塞bug,充值后自动退款1.5倍!现在想回滚版本吗?现在等待它慢慢编译。这个时候,如果编辑耽误了,公司就会破产。

在上述架构中,如果在线用户遇到难以排查的问题,也可以发布特定版本,用户在配置中心进行修改后可以访问特定版本的页面,更方便排查问题。它简化了流程。

目前来说,你实际上可以通过这个方案来实现一些小流量的配置、AB实验、版本控制等。

该方案的优点:可以随时调整,不需要后端版本,可以适配移动设备。

该解决方案的缺点:

与服务器强绑定(需要用户信息,但无法避免)。

每次都必须从CDN 加载HTML,这会浪费一些性能。但是,如果HTML 被缓存,则在发布过程中必须通知服务器,从而增加了整体复杂性。

考虑CDN 故障会使服务器端的CDN 降级变得复杂。

常见要求包括版本控制/低流量,并且必须开发或访问该解决方案中的每个后端应用程序。

一般配置中心一般采用JSON配置,相对简单,无法绑定一个版本的多个环境,依赖手动配置,存在出错的风险(例如版本v1.2501是手动配置的)。在配置中心,它被错误地更改为v1)。

前端发布服务的实现与设计

也许有些同学在实现线上产品的版本控制时,需要在自己的代码中添加版本控制(例如发布后手动/自动打标签),然后根据需要重新发布部署,有些人可能会误以为这样就可以满足要求。然而,如上所述,源代码版本控制不灵活,无法适应商业环境不断变化和复杂的需求,无法一键秒级切换版本。

那么如何进行版本控制呢?答案是对所构建的产品进行详细的处理和管理。

同时,由于版本控制/小流量是前端部署常见的公共业务需求,应该与业务后端服务分离,因此我们在这里提出一个纯粹针对前端部署的新公共服务。这里称为Page Server,用于具体的Index.html文件管理,承担Nginx流量、业务后端流量等。

同时考虑到版本控制、小流量策略等频繁调整,

,每次调整不应该都登录服务器,故我们需要一个新的服务 & 界面,用于操作管理版本、调整小流量等信息,并且与上述 Page Server 同步,此处我们将该服务称之为 Page Config Web。

而我们的 Page Server 则可能会有很多个实例,部署在多个集群上,以满足跨国部署、多部门项目部署等要求。所以理想情况下 Page Config Web ****还要承接 PageServer 的创建、管理、配置等工作。所以 PageConfigWeb 与 PageServer 是 1 比 N 关系(或M比N,用于跨国部署等)。

同时,我们一个前端项目可能有多套前端环境,PageSever 在固定集群算公共设施,这些环境理论上都可以由一个或多个 PageServer 承载。故一个 PageServer 和多个前端环境是 1 比 1 或者 1 比 N 关系。

此时,对于 Nginx 来的流量,我们需要一种机制来区分该流量属于哪个环境实例,比如通过 URL 来区分,我们可以称之为 路由。

最后,为了保证上述服务的正确性和自动化,构建部署(新增版本)完成后,要同步到上述两个服务,以确保版本管理的正确性。

最后,大致的流程图如下:

超大图预警

本质上来说,相当于有一个公用的中间服务,部署在多个集群上,与构建发布过程深度绑定,用于承接HTML 的流量,并通过 Web 站点设置小流量规则、版本等等,来满足多变的上线需求。

其中,PageServer 在承载 HTML 服务时,可做一些其他工作,比如:

SSR
CDN 降级,用于 CDN 异常时直出 HTML 中将静态资源替换为可用的 CDN 站点。
404 处理
兜底页(比如服务出现故障,短时间内无法修复时出兜底)
模板渲染(如做模板替换,将 query 替换到模板中等)
特殊时期全局处理,如注入全局样式将页面全局置灰

等等等等。

PageConfig Web 和 PageServer 中有构建后的所有版本信息,理论上可以缓存每个版本的 HTML文件,并且为了优化性能,PageServer 中可将最新全量版本的 HTML 文件缓存到内存中,最大程度提升响应速度,其余版本存储到 Redis 等缓存中。

下面以发布一个正式版本 v.1.0.2502 并且回滚过程为例:

代码合并,触发自动化构建,构建产物以环境(env)+版本(env) + 版本(env)+版本(version) + name-hash 方式组织,并上传到 CDN。
构建完成后,构建脚本通知攻城狮同学、同步 PageServer、PageConfig Web 服务有新版本 v.1.0.2502 。

结尾

学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。

#以上关于2021年前端部署的灵魂拷问的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91992.html

(0)
CSDN的头像CSDN
上一篇 2024年6月24日
下一篇 2024年6月24日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注