GrowingIO SaaS 产品 CI/CD 实践 (一)

作者:郝阔君
GrowingIO QA Leader,曾任职于中国惠普、奇虎 360。带领 QA 团队负责 GrowingIO 全产品线质量保证工作,目前专注于 DevOps 实践,帮助团队提升质量和效率。

目的

本文主要描述 GrowingIO 过去在 SaaS 产品线上 CI/CD 的一些实践。由于历史原因公司使用的部分工具链比较小众,当前的 CI/CD 的流程还有很大的改进空间 ,但是一些实践经验还是有一定借鉴意义的。

什么是 CI/CD

CI/CD 是一种通过在应用开发阶段引入自动化来频繁向客户交付应用的方法。CI/CD 的核心概念是持续集成(Continuous Integration)、持续交付(Continuous Integration)和持续部署(Continuous Integration),业界对 CI/CD 理解如下。

CI 持续集成(Continuous Integration)

GrowingIO SaaS 产品 CI/CD 实践 (一)_第1张图片

持续集成是一种开发实践,在持续集成环境中,开发人员将会频繁地向主干提交代码,这些新提交的代码在最终合并到主干前,需要经过编译和自动化测试流进行验证。

持续集成是在源代码变更后自动检测、拉取、构建和(在大多数情况下)进行单元测试和静态质量分析的过程。

持续集成的目标是快速确保开发人员新提交的变更是好的,并且适合在代码库中进一步使用。CI 的流程执行和理论实践让我们可以确定新代码和原有代码能否正确地集成在一起。

CD 持续交付(Continuous Delivery)

完成 CI 中构建及单元测试和集成测试的自动化流程后,持续交付可自动将已验证的代码发布到存储库。为了实现高效的持续交付流程,务必要确保 CI 已内置于开发管道。持续交付的目标是拥有一个可随时部署到生产环境的代码库。

GrowingIO SaaS 产品 CI/CD 实践 (一)_第2张图片

在持续交付中,每个阶段(从代码更改的合并,到生产就绪型构建版本的交付)都涉及测试自动化和代码发布自动化。在流程结束时,运维团队可以快速、轻松地将应用部署到生产环境中或发布给最终使用的用户。

CD 持续部署(Continuous Deployment)

对于一个成熟的 CI/CD 管道(Pipeline)来说,最后的阶段是持续部署,持续部署可以自动将应用发布到生产环境。

GrowingIO SaaS 产品 CI/CD 实践 (一)_第3张图片
持续部署意味着所有的变更都会被自动部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。

持续交付并不是指软件每一个改动都要尽快部署到产品环境中,它指的是任何的代码修改都可以在任何时候实施部署。持续交付表示的是一种能力,而持续部署表示的则是一种方式。持续部署是持续交付的最高阶段。

如何实现 CI/CD

实现一套 CI/CD 流程主要有以下几种途径:

1. 购买现成的产品或服务

很多成熟的产品都提供完善的 DevOps 功能,如 Atlassian、微软的 Azure DevOps、阿里的云效、coding.net 等等。如果是全新的初创公司可以选择购买合适的产品和服务,可以借助 DevOps 产品提供的工具和最佳实践,快速搭建起一套完善的 DevOps 体系。很多 DevOps 服务都是跟云厂商集成的,如果已经使用了对应的云服务产品,再使用对应的 DevOps 服务其成本并不高。

2. 将现有的一些工具集成起来

这是目前多数公司最常见的一种做法,将公司内部的项目管理,代码管理,制品管理等工具集成起来,或做一些简单的二次开发实现一套完整的 CI/CD 流程。这种方式总体成本可控,利用现有的基础设施进行改造,方便灵活,可以根据公司自己的流程来定制。

多数公司都是采用这一种方式,因为多数公司创立之初,必然是先生存后发展,并不会把工程效率放在第一位,会选用一些单独的工具(如代码管理)解决某一领域的问题。随着公司发展才会更多的考虑工程效率,此时将现有工具集成起来显然是最常见的选择,GrowingIO也不例外。

3. 使用一些开源的 DevOps 平台

目前也有一些开源产品,已经基于各种开源产品做了二次开发集成,形成了完整的 DevOps 平台,如猪齿鱼。如果不想购买云服务,又不想做二次开发,可以尝试此类工具。

不过值得注意的是,使用开源工具的资源投入并不一定会少,尤其是出现问题需要解决,或者说工具不能满足自身需要时需要二次改造,都需要对工具进行深入的研究和了解,所以选择这类产品也要考虑是否与公司当前的技术栈匹配,是否有能力进行维护。

4. 自己设计开发实现

自己新造轮子,重头开始设计开发实现一套。显然这种方式是投入成本最高的,但也是最灵活,最能符合企业自身需要的,一般都是一些特大型的企业才会花费资源来研发。比如上面第一种提到的一些云服务产品起初都是企业内部自己研发使用,成熟以后作为产品对外提供服务,从而获取更多经济回报。

使用的工具

工欲善其事必先利其器,要实现一个经济高效的 CI/CD 流程选择合适的工具可以实现事半功倍的效果。一个典型的 CI/CD 流程建设至少需要具备以下功能的工具。

  • 代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库
  • 持续集成服务器,用于自动执行构建,测试,部署等任务
  • 集中的制品管理仓库,用于存放构建的成果物,用于部署
  • 自动部署工具,用于将构建到的程序自动的部署到目标服务器
代码管理 Phabricator

GrowingIO 成立之初就选择了私有化部署 Phabricator 作为开发协作工具,Phabricator 是一款与 GitHub、GitLab 等类似的强大的软件开发协作工具,其支持Git、Mercurial、Svn 三种代码仓库托管、代码 Review、命令行工具、任务管理、看板、Wiki、自动规则,WebHook 和 API 等多种功能。

持续集成服务器 Jenkins

目前可以实现持续集成的自动化工具有很多,其中最流行开源工具莫过于 Jenkins 。Jenkins 支持多种任务类型,1000+ 插件,社区和生态都比较完善。Jenkins 2.0 版本提供了 Pipeline as Code 的特性,可以将 CI/CD Pipeline 的定义纳入版本管理,支持 GitOps。此外,Jenkins 支持多种方式实现的主从架构,其中借助 Kubernetes 强大的编排和调度能力而实现的主从模式,可以实现从节点的动态创建和销毁,极大的提升了 CI 执行效率和资源利用率。

质量管理平台 SonarQube

SonarQube 是一款代码质量管理平台,通过 SonarQube 可以检测出项目中潜在的 Bug、安全漏洞、代码规范、重复代码、缺乏单元测试等代码质量问题,并提供了 UI 界面进行查看。可以通过控制相关代码质量指标的阈值,保持和提升代码质量。使用 SonarQube 免费的社区版,就已经可以满足绝大多数的项目需求,而且它还很容易跟第三方的 CI/CD ,Code Review 工具集成。

制品库管理 Nexus

Nexus 是 Sonatype 开发的一款制品仓库管理工具,支持 Maven,NPM,PyPI,Docker,Helm 等数十种制品的管理,此外他还支持 Webhook,REST API 可以很方便的与第三方工具集成。Nexus 的免费的开源版本(即 Nexus Repository OSS)所提供的功能已经可以满足我们的绝大多数需求。

部署工具 Capistrano

Capistrano 是一款 Ruby 语言实现的,免费开源的远程服务器自动化管理工具。Capistrano 是基于 SSH 的免代理模式运行的,只需要安装一个客户端即可轻松的实现多台服务的管理。Capistrano 提供了一套用于部署和回滚的 DSL 和工作流,可以很容易的实现服务的远程自动部署和回滚。同时还可以很容易通过自定义插件或脚本扩展功能,实现个性化需求。

此外除了以上工具还使用了 Kubernetes,Docker 等工具。这里提到工具所提供的功能都有很多其他的替代方案,需要根据公司具体的技术栈,当前使用工具,工程实践,部署方式等多种因素选择。

源代码管理策略

源代码管理作为 CI/CD 的起点,会与 CI/CD Pipeline 深度的集成,不同的代码分支策略会影响 CI/CD Pipeline 的设计实现,所以在开始设计 CI/CD 之前必须根据公司当前的协作流程设计好分支管理策略。

Git 分支管理的方案有很多,他们各有优缺点,都有各自的试用场景,其中比较出名的有 git-flow 、trunk-based 、github-fow,各个企业也会自定制自己的分支策略,如阿里巴巴的 AoneFlow 。

GrowingIO 倾向于使用 Trunk-based 的分支策略,其最理想状态的是「主干开发,主干发布」,要做到这一步对代码开发的质量要求相当高。

目前公司的开发实践还无法达到这样的要求,所以退而求其次使用「分支开发,主干发布」,当分支生命周期很短时,基本不会产生代码合并冲突,就基本等同于主干开发。在主干分支出现 Bug 影响发布的时候也会临时采用分支发布的策略。

分支说明
Master 分支

Master 分支是最新的代码集成主干分支,同时是发布(Release)分支,一般当代码通过充分测试后才能进入到 Master 分支,Master 分支是随时可发布状态。

该分支禁止直接 git push,必须通过提交修改 Diff (等同于 Github 的 PR,Gitlab 的 MR,是 Phabricator 中进行代码 Review 的单元) ,通过 Code Review 和测试验收后,才能合并。

Release 分支

Release 分支是一个临时分支,主要是为了解决有些情况下 Master 分支不满足上线条件但是又需要紧急上线的时候使用。

例如上线过程中发现某一个修改引入了比较严重的 Bug,为了不影响其他修改的正常发布,通常会将有问题的 Commit 剔除掉,然后创建一个临时分支继续发布。

Feature 分支

功能开发分支或集成测试分支,是开发过程中最活跃的分支,每次提交到该分支的代码都会被集成。在微服开发模式下,开发人员很难在本地搭建完整的集成环境,因此需要云端的集成测试环境来帮助开发完成联调测试。

如果在代码进入主干分支之前通过集成测试,QA 验收,和产品验收,无疑会大大降低代码进入主干分支的风险。当然要保证 Feature 分支的生命周期足够短,这样可以大大的避免代码合并冲突。

Trunk-based 反对使用长生命周期的 Feature 分支,鼓励使用特性开关和抽象分支技术来尽快的合并代码到主干分支,同时又不影响主干分支功能。

Local  分支

开发者本地分支,之所以是本地分支是因为 Phabricator 允许在不创建远程分支的情况下提交 Diff 进行代码 Review 和部署。

开发分支的代码经过本地调试和单元测试后会基于主干(Master 分支)或 特性分支(Feature 分支)提交 Diff 进行 Code Review ,Review 通过后进入对应的 Base 分支。

Feature 开发流程

通常要实现一个比较大的 Feature 需要数据端多个组件,服务端多个微服务以及前端协同开发才能实现。EM (工程经理,Engineer Manger)在 Sprint 计划时将 Feature Ticket 拆分成多个子任务,交由不同的开发来实现。

  • 各个模块的开发人员,从 Master 创建 Feature 分支,并推送到远程 ,如下图的 Feature 1 分支
  • 对应模块的开发人员,从 Feature 分支创建一个本地开发分支,用于实现一个子任务,多个开发同时在一个代码仓库工作时可以各自创建自己的本地分支, 如下图的 Dev1, Dev2 分支
  • 开发人员在本地开发调试,并执行单元测试通过后,提交 Diff 进行 Code Review (CR) ,如果 CR 不通过则修改代码更新 Diff 直到 CR 通过后合并到 Feature 1 分支,然后删除本地的开发分支,如下图的 Dev1 分支。当另一个开发完成本地开发需要提交 Diff 时,要先 Rebase Feature 分支,然后提交 Diff,通过 CR 后合并进入到 Feature 1 分支,并删除本地分支,如下图 Dev 2 分支。当需要在 Feature 1 分支继续实现新功能或修改 Bug 时,重新创建一个本地分支
  • Feature 分支的代码会部署到对应的集成测试环境,供多端开发人员进行联调测试
  • Feature 分支联调通过后,在基于 Master 分支再提交一个 Diff ,然后提交 QA 测试,QA 测试通过后合并进入 Master 分支,删除对应的 Feature 分支
  • 如果代码仓库的一个 Featrue 分支只有一位开发人员工作,可以直接 push,如 Featrue 2 分支,当代码通过集成测试后再提交 Diff 进行 Coded Review,CR 通过后进入主干分支。不过即使只有一个开发人员也建议使用提交 Diff 的方式向 Feature 分支提交代码,防止最后提交的的 Diff 过大,不利于 CR

TIPS:每次提交 Diff 之前都应该与远程 base 分支进行 Rebase 或 Merge 操作,防止代码合并时冲突。

GrowingIO SaaS 产品 CI/CD 实践 (一)_第4张图片

以上流程看似复杂,不过借助 Phabricator 的命令行工具 Arcanist 可以很轻松的实现。

这里有个问题是 Feature 分支与主干分支会有一定差异,如上图 Feature 1 分支创建以后,Master 分支新的变更并不会进入到 Featrue 1,这个可以通过 Featrue 1 分支在 CI 流程中自动 Merge 主干分支(在本地不会推送到远程),如果合并失败则 CI 流程失败,开发人员手工更新 Feature 1 分支,同步 Master 代码。

Hotfix 开发流程

Hotfix 开发流程与 Feature 类似,直接基于 Master 分支创建本地开发分支,开发通过后提交 Diff 进行,代码静态检查,单元测试,Code Review 和 QA 测试,通过后合并进入 Master 分支,发布上线。

有些情况下当 Master 分支已经合并了新的 Feature ,这时有紧急的 Hotfix 需要发布时,需要用到 Release 分支。可以基于上次上线的 Commit 创建一个 Release 分支,然后将 Hotfix 从 Master cherry-pick 到 Release 分支发布。

这时要保留 Release 分支,以防有新的 Hotfix 需要发布,直到下次 Master 分支发布后就可以删除 Release 分支。因为我们的 SaaS 服务,发布频率很高,这种情况较少发生。

CI 流程
基于 Feature 分支的 CI 流程

在 GrowingIO 总是存在多个 Feature Team 在并行开发不同的功能,每个 Feature Team 都有自己独立的开发联调环境(对应到 Feature 分支)。

开发提交代码到 Feature 分支,Jenkins 自动监测到对应代码仓库的代码分支变更,然后启动对应的任务进行代码的静态检查,单元测试,编译,打包,并部署到开发联调环境。

对于前端和服务端应用是打包成 Docker 镜像进行部署在对应分支的 K8S 环境,对于数据端应用是打包成 zip 包部署到基于 VM 的环境。

同一个 Feature 的代码都提交后,开发在开发环境进行联调测试。其关键过程:Git Push → Code Check → Unit Test  →  Build →  Deploy → Integrated Testing。联调测试通过后提交 Diff ,触发下面流程。

基于 Diff 的 CI 流程

开发提交 Diff 以后通过 Phabricator 定义的自动规则,自动调用 Jenkins 的 Webhook 触发对应的 Jenkins 任务进行与主干分支合并(并不提交到远程分支,只是检查有没有冲突)、代码静态检查、单元测试,Sonar 扫描、并通过 Jenkins 的 Phabricator 插件,将单测覆盖率等信息自动的添加到对应 Diff 的评论中。

如果上面的自动检查步骤失败或单测覆盖率不达标,则需要对应的开发修改,直到通过自动检查(当然有时候有一些紧急的 Bugfix 需要快速发布,也会放宽这一限制)。

当自动检查通过以后即可通知组内的其他开发人员进行人工代码审核,如果审核通过则通过 Phabricator 将 Diff 标记为 Accepted,此时 Phabricator 中定义的自动规则会自动的将 QA Team 添加到 Diff 的 Blocked Reviewer (如果 Blocked Reviewer 还没有 Accepted ,Diff 是无法合并到主干分支的) ,并通过邮件通知 QA 人员进行测试。

QA 人员根据需要会将对应的 Diff 通过手动运行 Jenkins 任务部署到对应的 QA 环境进行测试,测试通过以后会再次在 Phabricator 将 Diff 标记的 Accepted,并通知对应的开发 Land 代码(Land 是 Phabricator 的一个术语,即将代码合并到主干分支,并将 diff 关闭,等同于 Github/Gitlab 的 PR/MR merge),当然 QA 也可以直接 Land 代码。其关键过程:Create Diff → Auto Check → Peer Review →  QA Review →  Land。

下面是上述过程的简单流程架构图:

GrowingIO SaaS 产品 CI/CD 实践 (一)_第5张图片

发布策略

经过上面的 CI 流程以后,理论上已经进入到主干分支的代码是随时可以部署的状态。但在实际实践中出于对质量保证和发布成本的考虑,会控制发布节奏。

我们采用的是基于固定发布周期的敏捷发布火车模式(Agile Release Train, ART),正常每周一个正式版本(区别于 Hotfix 版本)发布,一般在周二晚上部署。

质量要求

上面也提到了,GrowingIO 是多个 Feature Team 并行开发,虽然每个 Feature 提交的代码都是经过测试才进入到主干分支,但是在一个发布周期内多个团队可能对同一个代码仓库作出修改,多个 Diff 相互影响可能引入新的缺陷。

还有就是在 Diff 测试的时候一般会关注在 Diff 自身的修改可能影响到的部分,虽然开发、测试会尽可能的分析其影响范围,但受制于每个人的知识以及系统的复杂性,一个 Diff 修改可能引起完全想不到的地方出现缺陷。

所以,在发布前必须对要发布的功能进行比较全面的回归测试(在这方面我们不止一次的犯错 ̄□ ̄||)。这一回归过程大概需要整个 QA Team 半天到一天的工作量,回归测试中发现的缺陷要求立即修复。

此外,回归测试期间会进入 Code Freeze 阶段,所有涉及发布的代码仓库禁止开发 Land 代码到主干分支,只有 QA 有权限 Land 代码到主干分支。

这样做的主要目是避免已经回归测试过的功能,因为新代码引入 Bug;同时又保证回归测试的 Bugfix 能够进入主干分支。如果回归测试中发现的缺陷无法短时间内修复需要将有问题的 Diff 在发布分支剔除,定位到引入问题的 Diff 然后  Revert。

TIPS:回归测试发现缺陷以后为什么不延期发布?

  • 因为「火车」上有其它货物(新 Feature 或 Bugfix)需要按时交付给客户。
  • Code Freeze 时间过长将影响正常的迭代,代码不能合并到主干,后面有依赖开发受阻。
  • 如果取消 Code Freeze 延期发布又要重新做回归测试,浪费人力物力。
成本考虑

上面提到了,每次正式版本发布需要做全面的回归测试,如果频繁发布必然会导致大量的人力耗费,再者 QA 都去做回归测试了,谁来做 Diff 测试?

这个问题解决的方案是提升回归测试的效率。一是加大回归测试的自动化测试覆盖率,二是采用一些精准测试策略,降低不必要的回归测试执行。但这些都需要一些资源投入来慢慢建设,短期内较难达到,所以选择合理的发布节奏是最简单有效的方式。

特性开关

有些时候,已经进入主干分支的某个新功能并不希望用户看到,可能是出于市场宣传的考虑,也可能是功能还在迭代中还不够完善等原因。这种情况可以使用特性开关(Feature Toggle)控制。

目前 GrowingIO 的 Feature 开关可以实现,按照客户组织 ID,客户项目 ID,用户邮箱,用户邮箱后缀,以及自定义脚本规则进行各种精细化的 Feature 控制,这些配置可以通过修改配置文件实现热更新。

部署策略

部署前准备

回归测试通过以后,QA 团队会进行发布前准备工作,主要包括以下几方面:

  1. 生成 Jira Release Notes,检查 Jira 中 Release Version 关联的 Ticket 是否都是完成状态。
  • 如果是未完成状态,检查是状态没有及时更新的,更新状态。
  • 如果是未完成状态,如果是没有完成的移动到后续版本。
  • 如果是回归测试中发现有问题的 Diff 被剔除了,对应的 Ticket 也要移到后续版本。

2.生成工程 Release Notes

  • 包含上线执行步骤,上线哪个代码仓库的哪个分支,一般都是 Master。如果有特殊操作说明,如需要修改配置或执行 SQL 脚本的都要详细说明。
  • 详细的修改清单,本次发布包含哪些新的 Diff 以及其对应的 Jira Ticket。主要是方便上线后出现问题以后通过本次上线的修改清单,快速的定位到可疑的 Diff,进行问题排查。
  • 每次上线即使是简单的 Hotfix 也必须提供发布清单。
  • 发布清单都有特定的版本号,版本号与Jira 的 Release Version 对应。
  • Release Notes 生成以后会发布到研发群中,请各个团队进行 Review。

TIPS:工程 Release Notes 主要通过脚本自动的检查所有要发布的代码仓库,自动生成,然后有必要时进行简单的人工调整。

GrowingIO SaaS 产品 CI/CD 实践 (一)_第6张图片

部署准备

发布清单准备就绪后 QA 团队会通过钉钉群向 SRE 团队提交上线申请,SRE 团队收到上线申请后,会检查上线清单的步骤是否清晰明确,并熟悉发布内容。如果确认无误会提前通过 Jenkins 编译本次要发布的代码,提前做好部署准备。

部署过程

东风速递,使命必达 ,到达预定的发布时间点以后,SRE 会开始部署。为了保证部署过程中服务不中断,GrowingIO 目前采用的服务端部署方式是蓝绿滚动部署方式。

我们线上有两个相似的服务端集群,这两个集群中的微服注册在独立的 Goup 中,流量相互隔离。部署过程中会先将 Prod0 集群下线,此时客户流量全部进入到剩下的集群 Prod1,SRE 会按照部署清单更新 Prod0 中的服务,当部署完成后会通知 QA 在 Prod0 集群做验证。

QA 验证通过以后会通知 SRE 团队,继续发布。此时 SRE 团队会将 Prod0 集群上线,然后下线 Prod1 集群,并更新 Prod1 集群。

Prod1 集群更新完毕以后会再次通知 QA 在 Prod1 集群验证。QA 验证通过以后会再次通知 SRE 团队,继续发布。SRE 会将 Prod1 集群上线,并通知部署完成。

这里需要说明的是数据端的应用发布采用的是滚动发布策略,所以是会随着 Prod0 发布一起发布的。

当然,虽然经过了各种前期的准备和测试,但是意外还是可能发生,不过几率很小。如果在上线过程中 QA 验证发现严重问题,或者 SRE 通过监控告警发现异常会终止上线,并回滚相关服务。

整个部署和回滚操作都是由 Jenkins 执行 Capistrano 脚本完成的,具体的部署细节并不需要人工干预,多数情况下,整个部署过程会在 30 分钟内完成。

部署收尾

部署成功后 QA 团队会发送 Release 邮件,通知公司全体成员本次发布的版本中包含的详细内容,即部署前准备工作中的 「Jira Release Notes」 和「工程 Release Notes」。

前者面向业务人员阅读,后者面向工程人员,这样整个公司的人员都可以及时了解到自己关注的新功能或者 Bugfix 是否上线了。

问题与不足

上述 CI/CD 流程还有很多不足,最重要的问题有以下几点。

1. 基于源代码发布

目前 GrowingIO SaaS 服务的发布,不论是部署到 Dev, QA, Staging 还是 Prod 环境都是基于大代码分支重新编译然后部署。每次基于源代码发布的问题在于:

  • 浪费时间,每次发布都要重新编译代码,有些服务编译时间较长,甚至达到 10 分钟。
  • 可能因为每次编译的基础环境不同,远程依赖版本的一些变化导致编译出的代码不同,导致测试没问题上线后出现问题。

这个问题比较容易解决,例如在 GrowingIO 私有化部署产品线实现的 CI 流程,已经实现了基于二进制包的交付,从而实现了一次编译,多套环境部署,当然,这里有个基本前提是代码与配置分离。SaaS 没有当前进行改造的主要原因是打算等生产环境采用基于 Kubernetes 容器云部署方式的时候一并解决。

2. 自动化测试覆盖度不够

高效的 CI/CD 流程离不开自动化测试的支持,目前 GrowingIO 整个 SaaS 产品的单元测试,API 自动化测试,UI 自动化测试覆盖率还不够完善,导致整个流程对手工检查的依赖过高,效率偏低。这个依赖于公司在在质量保证方面的持续投入,来逐步改善,没有捷径可走。

3. 整个 CI/CD 流程分成了多段,通过邮件,钉钉,jenkins 人工串联起来

目前整个 CI/CD 的流程分成了 Feature CI 流程,Diff CI 流程,部署流程,三个流程通过邮件通知,钉钉消息,不同的 Jenkins 任务串联起来。随着公司规模的扩大,这样的协作流程会变得越来越混乱低效,而且很难做到数据的收集度量。

解决这个问题的有效方法是开发一个工具平台将流程和工具集成起来,提供统一的管理入口、流程规范,并实现数据的自动采集分析。

4. 部署过程过于复杂,不能实现更轻量滚动发布和金丝雀部署

上面提到为了保证发布过程用户服务不中断,采用了滚动蓝绿部署的方式。这种方式部署时是将一半集群所有微服下线,此时线上提供的最大服务能力减半,在用户使用高峰期,这种操作显然风险极高,限制了发布时间窗口的选择。

此外,每次升级单个微服务的时候都要将整个一半集群下线,显然也是不够合理的。目前的计划是在生产环境使用基于 Kubernetes 的容器云部署方式来解决这一问题。

总结

本文主要介绍了 CI/CD 的概念,以及 GrowingIO SaaS 产品在内部采用的各种工具,以及在 CI/CD 上的具体实践。正如上面所述,我们目前距离成熟的 CI/CD 还有一定差距。甚至有些地方并没有遵守最佳实践,比如基于源代码的发布。

但是这些实践都是根据公司的实际情况一步步建立完善起来的,希望对大家有一些启发。另外本文主要描述了整个 CI/CD 的宏观流程,后续的文章会继续介绍一些具体的工具配置使用方法,以及 GrowingIO 在私有化部署产品中 CI/CD 的一些改进。

关于 GrowingIO

GrowingIO 是国内领先的一站式数字化增长整体方案服务商。为产品、运营、市场、数据团队及管理者提供客户数据平台(CDP)、广告分析、产品分析、智能运营等产品和咨询服务,帮助企业在数字化转型的路上,提升数据驱动能力,实现更好的增长。

点击「此处」,获取 GrowingIO 15 天免费试用!

你可能感兴趣的:(程序员saasci)