跳到主要内容

前端部署问题

参考:

https://juejin.cn/post/7017710911443959839#heading-0

https://zxpsuper.github.io/advanced_front_end/book/browser/static.html

  • 前端代码从 tsx/jsx 到部署上线被用户访问,中间大致会经历哪些过程?

  • 上述过程中分别都有哪些考虑、指标和优化点,以满足复杂的业务需求?

  • 可能大部分同学都知道强缓存/协商缓存,那前端各种产物(HTML、JS、CSS、IMAGES 等)应该用什么缓存策略?以及为什么?

    • 若使用协商缓存,但静态资源却不频繁更新,如何避免协商过程的请求浪费?
    • 若使用强缓存,那静态资源如何更新?
  • 配套的,前端静态资源应该如何组织?

  • 配套的,自动化构建 & 部署过程如何与 CDN 结合?

  • 如何避免前端上线,影响未刷新页面的用户?

  • 刚上线的版本发现有阻塞性 bug,如何做到秒级回滚,而非再次部署等 20 分钟甚至更久?

  • 如何实现一个预发环境,除了前端资源外都是线上环境,将变量控制前端环境内?

  • 部署环节如何方便配套做 AB 测试等?

  • 如何实现一套前端代码,发布成多套环境产物?

  • 如何实现按 feature 发布产物供用户使用,并逐步扩大 feature 灰度,将影响减到最小(即线上同时存在多 feature 产物)?

  • CDN 域名突然挂了,如何实现秒级 CDN 降级修补而非再次全部业务重新部署一次? 本文将会带着这些问题,试着一起探索在2021年,系统化的前端部署解决方案。

前端静态资源部署 如何做到精确缓存控制?

后续发版上线时,只有被变更文件的 URL 会更新,实现了精确的缓存控制

但缓存还未到期我们发现有 bug,想更新 某个css文件怎么办?​

如果缓存还未到期,但是你发现了一个需要紧急修复的 bug,想要更新某个 CSS 文件,可以采取以下方法:

  1. 修改文件名:修改文件名,让浏览器无法使用之前的缓存,例如将 main.css 改为 main-v2.css。
  2. 查询字符串:使用查询字符串的方式来强制刷新文件,例如将 main.css 改为 main.css?v=2,浏览器会将查询字符串视为一个新的 URL,从而强制重新下载文件。

如果你想要同时实现尽量长的缓存时间和能随时更新的需求,可以使用版本号来控制缓存。例如,可以将 CSS 文件名设置为 main-v1.css,在文件发生更新时将文件名改为 main-v2.css,并在 HTML 文件中引用新的文件名。由于文件名已经改变,浏览器会重新下载新的文件,但由于版本号不同,旧的文件仍然可以被缓存。这种方法既可以保证缓存时间尽量长,又可以随时更新文件

如何给css文件,加上查询字符串参数。来强制刷新文件​

静态资源 查询字符串参数:就是资源地址路径末尾增加字符串参数,浏览器会视为一个新的URL

  • 要给 CSS 文件添加查询字符串来强制刷新文件,可以将查询字符串作为 URL 的一部分添加到 CSS 文件路径的末尾。

例如,如果你的 CSS 文件路径为 /assets/css/styles.css,可以将查询字符串 ?v=1 添加到路径末尾,变成 /assets/css/styles.css?v=1。这样,浏览器会将该 URL 视为一个新的资源,从而强制重新下载文件。

在实际开发中,可以通过以下几种方式添加查询字符串:

  1. 手动修改文件路径:直接在文件路径中添加查询字符串,例如在 HTML 文件中将

    <link rel="stylesheet" href="/assets/css/styles.css"> 修改为 <link rel="stylesheet" href="/assets/css/styles.css?v=1">。

  2. 使用构建工具:如果你使用构建工具(例如 webpack、gulp 等),可以使用插件或 loader 来为 CSS 文件自动添加查询字符串。

  3. 使用服务器配置:在服务器端,可以使用 URL 重写或反向代理等方式来自动为 CSS 文件添加查询字符串。

需要注意的是,虽然添加查询字符串可以强制刷新文件,但也会带来一定的性能损失和带宽浪费。因此,建议仅在必要时使用该方法,并考虑使用更灵活的缓存策略,例如使用版本号来控制缓存。

使用查询字符串来更新缓存,有什么弊端​

  1. 降低缓存效率:使用查询字符串来更新缓存会降低缓存效率,因为每次更改版本号都会使浏览器重新下载文件。如果文件比较大,每次更新都需要重新下载会浪费用户的时间和服务器的带宽。
  2. 带宽浪费:使用查询字符串更新缓存也会带来带宽浪费的问题。如果每次更新都需要重新下载文件,那么服务器的带宽将承受更大的压力。
  3. 不能精确控制缓存:使用查询字符串来更新缓存不能精确控制缓存,因为每次更改版本号都会强制更新缓存,无法控制缓存的粒度。如果只是对某些文件做了微小的修改,也需要重新下载所有文件,从而浪费带宽和用户时间。
  4. 不适用于动态内容:查询字符串只能适用于静态内容的缓存控制,不能对动态内容进行缓存控制。

CDN 域名突然挂了,如何实现秒级 CDN 降级修补而非再次全部业务重新部署一次?​

方式一:

一种实现秒级 CDN 降级修补的方法是使用 DNS 解析。假设网站主域名为 example.com,CDN 域名为 cdn.example.com,当 CDN 域名挂掉时,可以将该域名的 DNS 解析记录修改为指向备用服务器的 IP 地址。这样可以实现秒级的 CDN 降级修补,从而保证用户可以访问到网站的静态资源,而不影响业务的正常运行。

具体实现步骤如下:

  1. 配置备用服务器:准备一台备用服务器,用来存储网站的静态资源。
  2. 修改 DNS 解析记录:在 DNS 解析管理界面中,将 CDN 域名的 A 记录或 CNAME 记录修改为指向备用服务器的 IP 地址或域名。
  3. 配置备用服务器:在备用服务器上配置网站的静态资源,确保资源文件的路径和 CDN 域名下的路径一致,以保证能够正确加载静态资源。
  4. 测试修补效果:在修改 DNS 解析记录后,可以测试是否能够访问到网站的静态资源。如果可以正常访问,则说明修补成功,否则需要检查配置是否有误。
  5. 恢复 CDN 服务:一旦 CDN 服务恢复正常,需要将 DNS 解析记录修改回原来的设置,以恢复正常的 CDN 服务。

需要注意的是,在进行 DNS 解析记录修改时,需要考虑 DNS 缓存的影响,可以通过将 TTL 设置为较短的时间来加快 DNS 记录的更新速度,从而实现秒级的 CDN 降级修补。

方式二

  1. 使用多个 CDN 域名:在网站中可以配置多个 CDN 域名来分别托管不同的静态资源。当某个 CDN 域名出现故障时,可以将该域名的静态资源迁移到其他 CDN 域名上,从而实现秒级 CDN 降级修补。

部署流程​

谈谈部署流程,你是如何部署的?

  • docker
  • nginx
  • jenkins
  • gitlab cicd