阿里在使用一种更灵活的软件集成发布模式

当今典型的软件集成发布模式是,经过相似GitHub的Pull Request或GitLab的MergeRequest的方式管理特性分支(Feature Branch):在经过代码评审等方法确认一条特性分支上的改动没问题后,将其合入集成用的分支。随后,代码改动进入在集成分支上运行的持续交付流水线,直到发布上线。html

在阿里巴巴内部,尽管这种工做方式也获得了研发协同工具平台(Aone,对外叫云效)的支持,但广大研发同窗选择的主流工做方式却不是它,而是用一种被称之为变动(全称变动请求,英文Change Request)的对象来管理特性分支,直到发布。算法

初看起来,变动与Pull/MergeRequest有很多相同点,但实际它们在理念上的差异很大。微信

本文详细介绍它们的相同点和不一样点,并探讨用户喜欢变动这种方式的缘由,固然也会介绍相应的风险和弱点。或许阅读本文,能给你带来一些思考。架构

相同点

  • 变动与Pull/MergeRequest的相同点主要在于对特性分支自己的质量和流程的控制:
  • 一个变动,就像一个Pull/MergeRequest同样,大致上对应一条特性分支。
  • 在Pull/Merge Request中,能够看到这条特性分支上代码改动内容,进而进行代码评审(Code Review)。相似的,也能够以变动为粒度进行代码评审。
  • 在特性分支上的代码提交,能够自动触发持续集成工具作构建以及各类自动检测,其结果能够在Pull/Merge Request中展示。相似的,在变动中也能够展示。
  • 能够把Pull/MergeRequest上的最新代码构建部署到它专属的测试环境并运行,以进行测试和调试。在变动中也能够这样作。
  • 在Pull/Merge Request中能够设定经过的条件,好比至少两名评审者赞成,且全部的代码评审中发现的问题都已修复或澄清,且特性分支上的持续集成流水线运行成功。在变动中也支持相似设置。

不一样点及其主要价值

变动与Pull/MergeRequest的不一样之处关键在于,这个特性分支与其余特性分支一块儿集成和交付的方式。函数

对于Pull/MergeRequest,随后把特性分支合并到集成用的分支,而后就没有而后了。哦不,是而后就再也不以特性分支为粒度去管理了。这条特性分支已经合入集成用的分支,其上的代码改动已经融入集成发布的洪流之中,被裹挟着和其余特性分支上的代码改动一块儿前进,去闯关经过集成-发布的各个阶段(Stage)。微服务

而变动不一样。即使是已与其余变动集成,它仍然具备必定的独立性和灵活性,在确有必要时,可针对单独变动进行操做。下面咱们经过两个例子来详细介绍。工具

第一个例子:简化起见,假定集成交付过程有三个阶段:平常集成测试、在预发布环境测试、正式发布。某应用的变动A到变动E共五个变动,在经过了平常集成测试这个阶段后,进入了在预发布环境测试这个阶段。测试时,发现变动C有一个缺陷。这个缺陷由于受平常测试环境所限,在平常集成测试阶段没有暴露出来。经分析,变动C与其余四个变动间没有依赖关系,不会互相影响。所以,为了让其余四个变动的发布尽可能少受影响,决定把变动C从在预发布环境测试这一阶段中摘除出来。其余四个变动在一块儿再次测试验证,此时该缺陷再也不出现,这四个变动在一块儿经过了在预发布环境测试阶段,进而进入正式发布阶段,发布上线。测试

在这个例子中,在摘除了变动C后,没有将其余四个变动在一块儿再次通过平常集成测试阶段,是出于两方面考虑:一是,此时的平常集成测试环境,已经被若干新添的变动所占用。它们的测试须要时间,并且可能也会反复调整。把新添的变动赶出去,或者把这四个变动和新添的变动混在一块儿,或者让着四个变动等着,都分别有明显的不利之处。另外一方面,A、B、D、E四个变动,它们与变动C在一块儿,已经经过了平常集成测试。而变动C又与它们无关,所以对它们再次进行平常集成测试,发现问题的可能性很低。测试是要讲究性价比的,而不是一味追求保证产品零缺陷。出于以上缘由,在具体实战中,开发团队就有可能根据当时实际状况,在评估后决定,在摘除了变动C后,再也不将其余四个变动在一块儿送回平常集成环境,而是直接在预发布环境再次测试。ui

第二个例子:仍假定集成交付过程有平常集成测试、在预发布环境测试、正式发布三个阶段。某应用的变动A到变动E共五个变动,在经过了平常集成测试这个阶段后,进入了在预发布环境测试这个阶段。此时,根据市场状况变化,须要对变动C所承载的新功能作出少许调整,好比页面说明文案上改几个字。考虑到新的修改与变动C原有内容要么都发布,要么都不发布,因此为便于管理,新的修改就在变动C所在的特性分支上完成。这样造成的变动C的最新内容,与其余四个变动在一块儿,在预发布环境进行测试,经过后正式发布。阿里云

以上两个例子,是在传统的集成-发布方式基础上,加入了一些灵活性:集成-发布过程当中,必要时能够中途撤下变动,能够中途修改完善变动。而有些团队在使用变动时,采用了更进一步的方式:再也不设集成工程师之类的角色,再也不规划统一的集成、发布的计划和时间点。而是每一个开发同窗负责本身的变动,不只跟踪它直到把变动的质量提高到可集成的程度,并且由开发同窗本身把他负责的变动依次适时推入(也多是自动进入)集成-发布的各个阶段,跟踪它直到发布上线。也就是说,尽管进入了集成-发布阶段,各个变动还是被各自的开发者分别跟踪和推动的:它们可能有各自的推动速率和节奏,而不会相互拖累。彼此无关的变动,只是碰巧一同使用某个测试环境,一同批量测试以提升测试效率、一同上线以免排队而已。据此,尽量缩短了一个需求从开发到发布上线的时间,并表现为至关频繁的发布上线。同时也契合了DevOps的理念:“谁开发谁运行”(You build it, you run it)。

这一变化趋势其实和软件研发的管理实践中发生的事情相似:瀑布模型时代就不提了。随后迭代方法取代了瀑布模型。典型的,Scrum方法中的Sprint。而更进一步,在精益方法的看板墙上,迭代被弱化,关注的焦点从每一个迭代作什么,每一个迭代进入到什么阶段,演化为关注每一个在制品流动到了哪一个阶段,以及每一个阶段包含的在制品总量。

相似的,在上述变动管理方法中,从关注某个集成版本进入到集成-发布的哪一个阶段,演化为关注每一个变动进入到集成-发布的哪一个阶段,以及每一个阶段包含了哪些变动。

另外一方面的价值

以上,介绍的是使用变动管理方式带来的灵活性,以及由于灵活务实而带来的效率提高。变动管理方式,在信息记录和跟踪方面还有一些的好处:

要想方便地知道,本次测试、本次发布,到底包含了哪些特性,只要看看包含了哪些变动就行了。变动自己有说明文字,变动还能够关联需求、任务、缺陷等工做项,更详细地说明变动的目的。而在变动以外,也没有别的代码修改能够经过直接提交到集成分支等途径溜进来。

而从变动的视角,这个变动相关的全部改动,都在该特性分支上,而不会由于屡次反馈修改而散乱到各处。所以这些修改老是能够方便地一同查看,一同操做。同时,老是可以清晰地知道这个变动的状态,它到了哪一个阶段:开发完毕了吗?进入平常集成测试阶段了吗?已经正式发布了吗?等等。

变动能够关联需求、任务、缺陷等工做项,同时变动的状态是能够自动获取的。所以,看板墙上跟踪的工做项,从原理上就可能被自动移动,以反映其实际状态。协做和进展,在看板墙上尽收眼底。

弱点和风险

以上谈的都是这样的变动管理方式能带来的好处。那么,它有没有弱点和风险呢?

是的,它有。从大爆炸式集成到持续部署流水线,业界几十年来几乎一直在采用一个基本模式:老是一个集成版本,去顺序经历集成-发布的各个阶段。这样能够保证,下一阶段收到的内容,老是精确的通过了上一个阶段的检验。而本文介绍的变动管理方式所引入的灵活性,意味着颠覆了这一基本模式。灵活性历来都是双刃剑。灵活性意味着风险增长,意味着可能被滥用。

敏捷宣言认为“个体和互动高于流程和工具”,上述变动管理方式暗合了这样的思想。但在实际使用该方式时,须要注意到它对团队成员提出了更高的要求:要求他们在具体场景具体案例中,可以对变动间的相关性及相应风险作出评估,并了解不一样选择对效率的影响,最终综合作出特定场景特定案例中的决策。具体来讲:

  • 变动对应的代码改动越少,中途撤下变动带来的风险越小。
  • 中途修改完善变动所对应的代码改动越少,带来的风险越小。
  • 软件架构越好,变动中途撤下或修改完善带来的风险越小。
  • 本次变动与其余变动的相关性越小,中途撤下或修改完善带来的风险越小。
  • 越紧急,越考虑灵活处理。
  • 业务角度,对软件质量的要求越高,就越不要考虑灵活处理。

延伸一下,事实上,在微服务甚至函数服务时代,即使不使用上述变动管理方式,也有相似上文的风险,也相应须要团队成员具有相似上文的自主判断能力。为何这么说呢?

之因此把单体应用拆分为微服务甚至函数服务,一个重要缘由就是为了每一个服务能单独测试和发布上线。然而,在使用微服务甚至函数服务方式时,被测对象严格地讲并非一个服务,而是该服务以及测试环境中与其直接或间接打交道的全部其余服务。而当把每一个服务单独测试和发布时,就常常会致使本阶段测试时某个其余服务的版本,与下个阶段测试时的版本不一样,或者与未来正式发布运行时的版本不一样。因而就意味着相似上述变动管理方式中的风险。

相应的,这里面就须要人来判断(固然能够有智能算法的辅助),本次哪些服务上的改动务必要一块儿测试和上线,而另外几个服务上的改动能够单独运做。而下次可能又是不一样状况,要根据下次的具体状况判断。

由此看来,“老是由一个集成版本,去顺序经历集成-发布的各个阶段”这个基本模式,其实已经被悄然突破了。上述变动管理方式,只是使这个突破更加明显了而已。

落地及工具支持

以上是介绍了一种独特的变动管理方式,介绍了优势,也介绍了相应的风险。下面咱们来看看它在阿里是如何落地的。

首先须要一套分支方案来支持它。大致上是这样:

  • master分支老是表明最新已发布版本。
  • 代码改动老是在特性分支上完成。特性分支老是从master分支上拉出的,并在必要时从master再次同步。
  • 没有一条长期存在的集成发布用的分支。而是集成发布过程的各个阶段,各对应一条短时间的,被自动管理的集成发布分支。从master分支自动拉出该分支,再把各特性分支自动合并到该分支(出现冲突时人工介入),因而它上面就有了用户想要的各特性。
  • 若是发现某个特性须要进一步修改完善,在特性分支上完成,并再次合并到相应的集成发布分支。

在阿里,咱们如何管理代码分支?》这篇文章对上述分支方案有更多介绍。

云效 > 使用指南 > 持续交付 > 开发模式 > 分支模式》这篇文档是该分支方案的详细说明。

能够看出,这套方案,对工具平台的要求是比较高的:从界面角度,用户只须要管理各个集成发布阶段分别要有哪些变动。而工具平台要将它映射为对集成发布分支的管理,包括建立新分支或复用已有分支、从各特性分支到集成发布分支的合并等等。这里面也包括了很多算法,以尽量减小相同的合并冲突重复出现。

对工具平台的高要求,或许是这套方法多年来一直只是在阿里巴巴内部被广为使用的缘由。

很多曾在阿里巴巴工做过的同窗,出去后都念叨着没有这样的工具支持了。不过如今好了,就像Google基于内部的Borg对外提供了Kubernetes,阿里巴巴也基于内部研发协同工具平台Aone对外提供了云效

云效的公有云版和专有云版,都提供了上述方法的完整支持。不管是你对上述方法抱有兴趣仍是怀有疑虑,均可以尝试研究一下。

相关阅读:

在阿里,咱们如何管理代码分支

在阿里,咱们如何管理测试环境

 

原文连接 更多技术干货 请关注阿里云云栖社区微信号 :yunqiinsight

相关文章
相关标签/搜索