编者按:本文源自阿里云云效团队出品的《阿里巴巴DevOps实践指南》,扫描上方二维码或前往:https://developer.aliyun.com/topic/devops,下载完整版电子书,了解阿里十年DevOps实践经验。
让我们进入到阿里巴巴在交付阶段的一些实践,包括:
- 以应用和变更为核心的交付流程
- 基于变更的检查项和卡点
- 针对应用特征选择研发模式
应用与变更
进入到具体的实践之前,我们先介绍下阿里巴巴的应用和变更模型。
应用,是研发活动的载体,包括了代码库、部署环境、配置项、变更管理、发布流水线、运维等一系列要素。整个需求的开发交付过程都可以在应用中完成。应用上可以设置不同的角色,这些角色信息在研发的各个环节中会起到作用。比如谁能发布线上环境,谁有权限修改测试配置等。
变更,作为应用的重要组成部分,是一个抽象的概念。所有对线上的行为的修改都可以称之为变更,变更属于某一个应用。变更中可以包含一个或者多个不同类型的变更内容,最常见的变更内容类型就是代码变更。
变更有相应的生命周期,一个典型的变更生命周期为:开发中->发布中->完成。当一个应用有多个变更同时在开发和发布时,需要有一定的协调机制,比如是在一个临时的集成分支上进行集成,还是在一个常驻的 develop 分支上进行集成。我们称这种分支协作模式为“研发模式”。
创建变更通常是为了实现需求和修复缺陷。一个需求可能需要修改多个应用,也就是需要在多个应用上创建变更,而简单的缺陷修复可能修改一个应用就可以解决问题,也就是一个变更。所以工作项(需求和 bug)和变更是一对多的关系。
我们从两个视角来看一下:
- 应用部署视角:每次应用部署上线会包含一个或者多个该应用的变更,可能涉及多个工作项。
- 工作项发布视角:一个工作项的发布可能需要多个应用的先后部署。
- 这两个视角是有交叉的。作为平台和工具,应该更关注哪个视角呢?
- 如果偏应用,则要完成一个工作项的发布,开发团队需要自行协调多个应用的部署顺序,会产生一定的沟通成本。
- 如果偏工作项,则会出现一个工作项的一组变更在部署某个验收环境,其他的工作项的变更需要等待,影响了整体交付吞吐率。
- 如果想要兼顾这两个视角,则不可避免的需要使用大版本制,或者叫火车制,拉长了单工作项的交付周期。
阿里巴巴的 DevOps 工具选择偏应用的视角,主要保证单个应用的部署上线流程和质量,将部署的节奏交给开发团队灵活安排。
比如一个工作项的发布涉及三个应用的三个变更,这个工作项的开发可以选择在周一部署第一个变更,周二部署第二个变更,而这两个变更不会造成任何线上可见的修改;到了周四,产品希望该功能上线时,再部署第三个变更,需求正式发布。这种将部署应用行为与发布功能行为分离的模式,可以降低集中部署带来的风险。当然能够这样做的前提是需要有比较完善的自动化质量保障及卡点机制。
基于变更的检查项和卡点
变更是交付的载体,因此可以通过在变更上承载检查项来保证交付质量。最常见的检查项包括:
- 是否通过代码评审
- 是否通过安全扫描
- 是否通过单元测试/UI 测试
- 基于这些检查项会进行质量卡点,一般在如下的生命周期节点上:
- 从开发中进入发布中:需要满足一定的质量标准(比如单元测试通过率,覆盖率等)之后,才允许进入到发布中的状态,能进入测试环境进行验证。
- 发布到某个环境上:这时变更已经进入了集成流水线,完成了构建等,但如果要继续部署到某个环境,需要满足更多的验证条件。比如安全审核需要通过,才能发布正式等。
至于在哪些节点设置哪些卡点,应用负责人可以自行决定。多个检查项建议尽早同时开始,以提高效率。
从另一个角度来看,发布平台也可以对所有应用进行全局的卡点设置,针对某些卡点自动开启,且不允许取消。比如扫描到你的代码中依赖了有安全问题的 JAR 包,则要求必须进行修复,否则无法部署上线。这样就可以控制一些全局性的风险。
变更和应用中的发布流水线,提供了一个进行检查和卡点的框架。具体的检查工作由其它的专门的平台提供,比如测试平台、安全扫描平台、与特定业务相关的合规扫描等。
研发模式
如前文提到,为了能够让一个应用的多个变更协同开发和发布,我们需要采用不同的研发模式。研发模式的主要差别在分支合并策略,目前阿里巴巴主要采用下面三种研发模式:
- 主干模式
- Aone-Flow 分支模式
- Git Flow 模式
应用有大有小,在其上进行需求开发的并行度也不相同。
阿里巴巴有大量的的应用没有并行进行的变更发布。这类应用适合使用主干模式或者 Git Flow 模式。也有一些应用变更的并发度比较高,会出现一些发布节奏不同的问题。业界一般使用功能开关的方式解决这个问题。阿里内部采用名为 Aone-Flow 的分支模式来解决。
在 Aone-Flow 的分支模式下,开发人员的典型工作流程为:
- 提交变更,Aone-Flow 会创建一个集成分支,或者复用已有分支,自动将你的变更合并到这个集成分支。
- 当你发现你的变更有问题不能发布,可以“退出发布”,Aone-Flow 会自动创建一个新的集成分支,把剩余的需要继续发布的变更再合并进去。
- 当集成分支完成正式部署之后,会合并到 master 主干上。这个集成分支上的变更都会被标记“已完成”,并打上 Git Tag。
- 当需要回滚时,可以根据系统的记录同时将线上的版本和代码一起回滚掉(git revert)。避免出现无意把有问题的 master 代码发布上线的情况。
关于 Aone-Flow 的详细描述可以参看:https://www.infoq.cn/article/EaC4c6yiJrzZ_Gtaf9Ne
这里仅就主干模式和 Aone-Flow 进行一个简单的对比。
主干模式/Git Flow 模式 | Aone-Flow | |
---|---|---|
对并行功能开发的支持 | 功能开关,成本高 | 进入/退出 发布,有可能出现重复解决分支之间的冲突的问题 |
对重构的友好程度 | 友好,修改了之后 push 上去即可 | 重构容易产生冲突,在 Aone-Flow 中会出现重复解决冲突的问题。解决方案就是尽快的把重构的变更发布到线上,这样才能合并到 master |
对“快速上线”的友好程度 | 通过自动化测试的代码就会合并到公共分支(比如 master)。当需要进行发布时候,就会把这些功能都发布上去,如果自动化测试不能给你足够的信心,那么发布的风险就会提升,从而可能造成了大家不愿意去频繁发布,或者成为一个火车版本模式。 | 由于发布时候可以选择变更,每个变更可以不受其他变更的约束,单独尽快进行发布上线,发布风险比较小。 另一方面,前面提到的“重复解决分支冲突”问题也会督促开发者尽快把变更发布上线。 |
可以看到主干模式和 Aone-Flow 各有利弊。在阿里巴巴,为了能够更加快速独立的交付特性,有一多半的团队采用了 Aone-Flow。
总结
了解了上述的过程,以 Aone-Flow 为例,我们对一个需求的上线过程要经过的阶段进行一个图解:
这里只画了日常、预发和正式三个环境,在实际的流程中,还会有灰度,安全生产环境等,来尽量避免出现线上问题和故障。
另外在变更的开发阶段,阿里内部还采用了一些隔离测试环境的技术来帮助开发者进行特性级别的隔离测试联调,详见前序的隔离测试环境章节。通过上述的管控和流程,我们就得到一个比较安全的需求交付流程。
免费下载《阿里巴巴DevOps实践指南》
阿里巴巴合伙人和业界多位大佬力荐、何勉、陈鑫等17位阿里资深技术专家联袂出品、阿里十年DevOps经验沉淀总结、阿里巴巴DevOps落地实践一本通。
前往:https://developer.aliyun.com/topic/devops,下载完整版电子书。