惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
WordPress大学
WordPress大学
博客园 - 聂微东
博客园 - 【当耐特】
小众软件
小众软件
V
V2EX
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
月光博客
月光博客
宝玉的分享
宝玉的分享
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
N
News and Events Feed by Topic
雷峰网
雷峰网
Hugging Face - Blog
Hugging Face - Blog
量子位
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - 司徒正美
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
AI
AI
O
OpenAI News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Threat Research - Cisco Blogs
Jina AI
Jina AI
博客园_首页
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
Last Week in AI
Last Week in AI
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
IT之家
IT之家
V
Vulnerabilities – Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Google Online Security Blog
Google Online Security Blog
G
GRAHAM CLULEY
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News: Ask HN
Hacker News: Ask HN
P
Palo Alto Networks Blog
S
SegmentFault 最新的问题
T
The Exploit Database - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
V
Visual Studio Blog
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
如何利用 CDN 进一步的前后端分离
微信公众号 · 2018-09-13 · via 陈少文的网站

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

1. 开发背景

1.1 部署方式

如上图,简单描述一下应用的架构。

采用的是经典三层架构,接入层,逻辑层,存储层。其中,接入层和存储层,是全部应用共用的服务。逻辑层由 K8S 部署,每个应用会有多个实例。

接入层能支持的并发量很大,由一个 LVS 将流量分给 多个 Nginx 实例。

逻辑层主要是将代码以 Slug 的形式打包到基础镜像,然后进行多实例部署。为了保证数据一致性,逻辑层不会保存任何状态,状态全部需要通过外部服务的形式管理。

存储层提供各种状态服务,比如 MySQL、对象存储等。

1. 2 开发模式

如上图,简单讲一下目前的开发模式。

我们采用的是前后端分离的开发模式。后端采用的 Django,前端 Webpack + Vuejs。前后端的交互通过 index.html 和接口进行。

开发者服务分为两部分:CI,CD

CI,也就是开发者持续集成。开发者分别向同一个仓库,提交代码。为了确保开发质量,会做一些 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
3
4
5
6
7
8
<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 是后端数据库中的前端版本号。通过一定策略修改版本号,可以实现灰度测试、A\B 测试的效果。

4.2 前后端联调验收策略

前后端代码仓库分离之后,各自发布版本。

但是前端版本与后端版本,不一定能组成一个可以发布的应用版本。例如,在新的一期迭代过程中,前端完成了功能开发【f5.3.1】,但是后端的当前版本【b3.4.4】没有就绪。

针对正在迭代中的版本,我们约定一种发布模式,起名为红绿发布。

如果前后端当前版本联调,验收通过,那么将前后端版本标记为绿色。

如果前后端有一方,发生调整,会影响之前功能的正常使用,那么将修改的版本标记为红色。

直至下一次联调版本验收通过,则将前后端版本再次标记为绿色。