如何利用 CDN 进一步的前后端分离

2023年 1月 4日 17.5k 0

最近在优化一下项目,梳理整个链路之后,开始逐步优化,发现了很多可以改进的点。下面是对开发模式、部署方式的一些思考,希望对你有所启发。

1. 开发背景

1.1 部署方式

如上图,简单描述一下应用的架构。采用的是经典三层架构,接入层,逻辑层,存储层。其中,接入层和存储层,是全部应用共用的服务。逻辑层由 K8S 部署,每个应用会有多个实例。接入层能支持的并发量很大,由一个 LVS 将流量分给 多个 Nginx 实例。逻辑层主要是将代码以 Slug 的形式打包到基础镜像,然后进行多实例部署。为了保证数据一致性,逻辑层不会保存任何状态,状态全部需要通过外部服务的形式管理。存储层提供各种状态服务,比如 MySQL、对象存储等。

1. 2 开发模式

如上图,简单讲一下目前的开发模式。我们采用的是前后端分离的开发模式。后端采用的 Django,前端 Webpack + Vuejs。前后端的交互通过 index.html 和接口进行。开发者服务分为两部分:CI,CDCI,也就是开发者持续集成。开发者分别向同一个仓库,提交代码。为了确保开发质量,会做一些 Merge Request 流程。当代码合并到 master 分支之后,CI Runner 会被触发执行,编译前端 Webpack 工程,然后将编译生成的前端文件和后端代码推送到 SVN 发布仓库。CD,持续部署部分主要是由 PaaS Engine 提供。这是一套由 K8S 提供的部署引擎。

2. 开发问题

虽然采取的是前后端分离的开发模式,但是实际上代码仓库使用的是同一个。这是由于 PaaS Engine 只支持 SVN 方式部署。同时,PaaS Engine 是一套通用的部署引擎,并不会针对前后端开发模式进行特殊适配。使用同一个代码仓库进行开发,由于使用不同的目录,代码层面不会产生冲突,但是在部署上进行了强绑定 — 必须前后端一起部署。这导致了一系列问题。

  • 代码仓库大,GitLab CI 推送 SVN 慢
  • PaaS Engine 转发前端静态文件效率低
  • 在开发迭代过程中,线上问题不能即时有效修复
  • 正式环境不能进行灰度测试,只有一个版本
  • 前后端仓库权限混乱,职责不清
  • 不同地区、网络访问应用的速度差别大

3. 前后端更多的分离

个人认为前后端分离最大的意义在于,权责的分离。权,意味着可以自由选择技术,发掘一些有趣有用的东西,取悦自己,也为了更好的发展项目。责,不仅仅是按期完成任务,还意味着需要去思考项目的持续性,优化项目中的问题,预防可能的风险。第一步,拆分 Git 仓库。如上图,我们将整个应用拆分为两个 Git 仓库。前端同学负责前端的 Git 仓库,后端同学负责后端的 Git 仓库。第二步,分开部署。PaaS Engine 部署时,拉取的是指定 SVN 仓库代码。这是一个禁锢,应用开发者以为代码需要打包,整合在一起才能部署。在对应用进行优化的过程时,我逐步将前端第三方插件移动到 CDN。突然想到,为什么不将整个前端文件都放到 CDN 呢?当然可以!静态资源直接使用 CDN,不仅能实现高并发,还能低延时,降低网络和地域的差异。绝对是前端部署的首选。如上图,CD 过程被拆分为两个并行独立的步骤。后端依然走之前的发布流程,在 GitLab 合并代码,推送到 SVN 之后,借助 PaaS Engine 进行发布。前端除了 GitLab 上的 Merge Request 和 Code Review 流程,在部署时,不需要走 PaaS ,而是直接发布到 CDN。完成这两步,就实现了对前后端权责的再次分离。

4. 版本管理

前后端统一仓库时,一起部署,版本绑定,不会存在版本错配问题。但是,前后端分开部署之后,版本管理的问题随之而来。

4.1 前后端对版本文件的管理

前端的文件存储在 CDN,通过约定的目录结构可以实现对版本的管理。假设域名为 cdn.domain.com 。存储相对路径路径为:

1
2
/:version_id/js/xxx.js
/:version_id/css/xxx.css

对应的完整访问路径为:

1
2
https://cdn.domain.com/:version_id/js/xxx.js
https://cdn.domain.com/:version_id/css/xxx.css

在前后端分离模式中,后端依然需要吐出首页。通过控制 index.html 中引用的静态文件版本,可以达到对前端版本控制的目的。由于只有一套后端发布环境,同时,MySQL 等状态服务不支持回滚,后端的发布,一旦数据库字段发生变更将只能向前滚动。index.html

1
2
<script type="text/javascript" src="https://cdn.domain.com/{version_id}/js/vendors.js"></script>
<script type="text/javascript" src="https://cdn.domain.com/{version_id}/js/app.js"></script>

这里的 version_id 是后端数据库中的前端版本号。通过一定策略修改版本号,可以实现灰度测试、AB 测试的效果。

4.2 前后端联调验收策略

前后端代码仓库分离之后,各自发布版本。但是前端版本与后端版本,不一定能组成一个可以发布的应用版本。例如,在新的一期迭代过程中,前端完成了功能开发【f5.3.1】,但是后端的当前版本【b3.4.4】没有就绪。针对正在迭代中的版本,我们约定一种发布模式,起名为红绿发布。如果前后端当前版本联调,验收通过,那么将前后端版本标记为绿色。如果前后端有一方,发生调整,会影响之前功能的正常使用,那么将修改的版本标记为红色。直至下一次联调版本验收通过,则将前后端版本再次标记为绿色。

相关文章

KubeSphere 部署向量数据库 Milvus 实战指南
探索 Kubernetes 持久化存储之 Longhorn 初窥门径
征服 Docker 镜像访问限制!KubeSphere v3.4.1 成功部署全攻略
那些年在 Terraform 上吃到的糖和踩过的坑
无需 Kubernetes 测试 Kubernetes 网络实现
Kubernetes v1.31 中的移除和主要变更

发布评论