百度资深敏捷教练深度解析持续交付之全面

作者介绍

张乐,百度资深敏捷教练、架构师,IntelligentSoftwareDevelopment团队成员。超过13年项目管理和敏捷实战经验,曾任职于惠普、埃森哲等大型外企,负责大规模团队敏捷转型和工程效率提升,积累了丰厚的知识体系和实战案例。加入百度后,作为公司内先进软件工程方法和生产力的践行者、布道者,主导了百度云、百度金融、云安全等新技术产品的敏捷转型和DevOps实施,帮助团队从业务、过程、技术、组织和工具等多个层面建立起全面的持续交付能力。Gdevops全球敏捷运维峰会、TiD中国质量竞争力大会等演讲嘉宾。

一、持续交付与配置管理

持续交付和DevOps是当前敏捷开发和运维圈讨论最多和最热门话题之一,虽然距离这些概念的提出已经有段时间了,但是国内很多企业仍处于对相关实践如何落地和实施的探索阶段。

在今年举办的一些技术大会上,我分享过关于持续交付方法与实践的话题,从互联网时代对软件研发和运维的挑战出发,分析了行业普遍面临的问题和痛点,并提出了持续交付体系化的实施模型。但限于分享时间的限制,很多内容无法充分开展详细介绍。今天这篇文章,我们就来详细谈谈持续交付中非常关键的一个实践,只有这个实践做到位了才能确保持续交付的实施效果,同时它也是后续一系列其它实践的基础,这就是『全面配置管理』。

在正式开始之前,我们先来快速回顾下持续交付的实施模型。

上图是我整理的持续交付体系实施模型,我在公司内部都是用这个模型来做推广和实施的。这个模型从业务、过程、技术、组织四个大的方向入手,对实现持续交付的关键要素及其内部逻辑关系进行整理。实现思路是通过在业务层面形成需求分解和迭代机制,在过程层面实现可靠、可视化、可管控的全自动化交付流水线和一系列关键实践,在技术层面提供基础架构和应用架构的支撑,在组织层面强调跨职能团队和数据驱动改进机制,从而全面地建立起快速、低风险、持续的向用户交付价值的能力。

持续交付是对整个软件交付模式的变革,涉及到的内容非常多、非常广,在这个模型中大概有二十多个关键点。今天我们就聚焦一下,仅仅来谈模型中一个关键实践『配置管理』。

二、全面配置管理的组成部分

配置管理的概念大家肯定非常熟悉了,这是一个非常广泛使用的名词,但也经常容易被狭义的理解,比如被当做版本控制的同义词等。在持续交付领域,我们强调的是『全面配置管理』,也就是对项目所有的相关产物及其之间的关系都要进行有效管理,通过这种方式管理项目中的一切变化,实现项目中不同角色成员的高效协作,能够在任何时刻、使用标准化的方法,完整而可靠的构建出可正常运行的系统(而不仅仅是可工作的软件),并且整个交付过程的所有信息能够相互关联、可审计、可追踪,最终实现持续、高效、高质量的交付。

为了做到全面配置管理,并为持续交付后续实践奠定良好的基础,一般来讲至少要做好以下三个方面:

代码和构建产物的配置管理:包括制定有效的分支管理策略,使用高效的版本控制系统,并对构建产物及其依赖进行管理;

应用的配置管理:对应用的配置信息进行管理,包括如何存取配置、如何针对不同环境差异提升配置的灵活性;

环境的配置管理:对应用所依赖的硬件、软件、基础设施和外部系统进行管理,确保不仅交付了可工作的软件,而且整个应用系统能够正常、稳定地运行;

三、代码和构建产物的配置管理

1、制定有效的分支管理策略

我们首先要强调,需要进行版本控制的不仅是源代码,还有测试代码、数据库脚本、构建和部署脚本、依赖的库文件等,并且对构建产物的版本控制也同样重要。只有这些内容都纳入版本控制了,才能够确保所有的开发、测试、运维活动能够正常开展,系统能够被完整的搭建。

制定有效的分支管理策略对达成持续交付的目标非常重要。持续交付建议的方式是频繁的提交代码,并且最好工作在主干上,这样一来修改对所有项目成员都快速可见,然后通过持续集成的机制,对修改触发快速的自动化验证和反馈,再往后如果能通过各种维度的验证测试,最终将成为潜在可发布和部署到生产环境的中版本。那持续交付为什么这样建议呢?下面我们来分析下几种常见的模式及其各自的优缺点。

在实际工作中,普遍采用的分支管理策略无外乎以下两种:

基于分支的开发

这正是很多团队经常默认使用的模式,具体表现为接到需求后拉出分支,后面的开发都在分支上提交,每个分支生命周期较长,并且可能有多个并行分支,直到快要上线时甚至上线后才合并到主干。

分支开发模式,根据具体使用场景,还可以进一步细分为:

分支开发、分支发布、发布后合入主干

分支开发、分支测试、主干回归、主干发布

优势:

我曾接触过的一些团队,开始时会选择分支开发模式,因为多个功能可以完全并行开发,互不干扰。还可以按每个功能特性拉出分支,那么每次提交都是完整的功能特性,分支划分明确、版本控制的记录也会比较清晰易懂。并且由于不同需求的开发进度不同,可以选择某个先开发完成的功能特性进行合并、发布,而不会被其它分支上未完成的功能特性阻塞。

缺点:

那这种模式有没有问题呢?引用电影《无间道》中的一句话,“出来混,总有一天要还的”,我觉得用在分支开发模式中还挺贴切的。因为虽然使用分支暂时隔离了不同功能的代码,但系统的多个功能或者多个组成部分最终还是要集成在一起工作的。如果不同分支代码之间有交互,合并时可能会有大量冲突需要解决,包括文本冲突和语意冲突(更难发现和解决)。在实际项目中,进行代码合并时通常很容易出错,解决冲突也非常耗时。我曾见到一个团队有多个并行分支,在开发后期因为冲突太多,不得不指定两名对系统了解非常全面的高级开发人员专职合并代码,结果他们基本每天工作到后半夜,而且经常出现合并错误甚至遗漏合并的问题,这种方式非常痛苦。

分支开发模式,其实从本质上就是与持续集成的理念相互冲突的。持续集成是希望每次修改都尽早的提交到主干,主干总是处于最完整和最新的可用状态,充分验证后就可以用它来进行生产部署。而使用分支开发模式时,由于无法及时合并到主干,那么时间越长与主干差别越大,风险就越高,最终合并的时候就越痛苦。所以持续交付不推荐使用分支开发的模式。

权衡和建议:

在某些情况下,有时迫不得已要采用分支开发的模式,比如并行需求太多且相互干扰,或者在需求开发的同时有大块的重构工作要做,或者针对特定的用户开发特殊的功能,以及需要进行与主线无关的试验等等。

在这些场景下,拉出分支其实意味着已经在持续集成/持续交付上做出了妥协,那么我们建议至少要使用一些折中的方案:

尽量缩短分支的周期,最长也不要超过迭代周期;

每个分支上运行单独的测试流水线,保证质量。虽然这种方式浪费资源,而且其实也没进行”真正的“集成;

分支只与主干合并代码,分支彼此之间尽量不做合并;

分支定期合并主干上的变更;

分支定期检查与主干的偏离度。有这样一种方式,就是每次分支提交时,由工具自动尝试与主干进行合并,并在这个临时的合并版本上运行自动化测试,用来检查是否可以合并以及合并后是否可正常工作,持续集成工具Bamboo好像已经提供了类似功能;

当然,以上这些仅仅是经过权衡的折中方案,只能一定程度上缓解问题,解决问题的最好方式还是改变分支管理策略。

基于主干的开发

持续交付更倾向使用基于主干的开发(TrunkBasedDevelopment,TBD)模式,所有项目成员把代码都提交到主干上,提交后自动触发持续集成进行验证和快速反馈,通过频繁的集成和验证,在保证质量的同时提升效率。Google就在坚持使用主干开发模式,所有人的所有更改直接提交到Trunk上。

主干开发模式,根据具体使用场景,还可以进一步细分为:

主干开发、主干发布

主干开发、分支发布

优势:

相比于分支开发,主干开发模式有很多优势。首先是代码提交到主干,可以做到真正的持续集成,在冲突形成的早期发现和解决问题,避免后期的”合并地狱”,这样的整体成本才是最低的。另外主干会一直保持健康的状态,每次合入代码并验证后都可进行安全的发布。

难点:

主干开发模式有很多优势,但在实际使用场景中,也存在一些实施难点。

主干上功能开发完成时间有先有后,如果遇到有未完成的功能但又需要发布时,就需要一种方法屏蔽掉未完成功能,才能进行安全的发布;

主干上功能开发完成后,如果需要比较长的时间进行验收测试,那么此时为了确保发布功能的稳定性且所有功能是经过验证的,可能会限制新功能的提交,有的团队采用的封版、冻结主干的做法就是这种情况,这样的确会影响开发效率;

如果修改的功能非常复杂,或者要进行架构上的大范围重构,以上问题就更加明显和难以解决了;

如果团队规模比较大,同时工作在主干上的开发人员比较多,那么冲突的概率会比较大,持续集成的失败率可能比较高;

优化和建议:

其实上面提到的实施主干开发的难点,在实践过程中大多会遇到,但也基本都能找到对应的优化和解决方案。

增量式进行开发。通过功能拆解,把大需求分解成小的Story,每个Story很小可独立发布。把大的修改分解为一系列小的变更,增量修改的方式更可靠,风险也更低,这也与精益思想中小批量生产的理念一致;

主干开发模式也并不完全排斥使用分支,比如可以创建以发布为目的的发布分支,这样在执行发布测试和缺陷修复的时候,主干就可以进行下一个迭代的开发了,相当于通过并行工作提升了效率;

隐藏未完成的功能。常见的实践比如后端先行,后端系统可以先开发上线,这时由于没有前端流量,也可以实现隐藏功能的目的;另外可以引入功能开关(比如Google的Gflags,Java领域的Togglz等),通过配置来控制功能对用户的可见性。但需要注意的是,使用开关也是有成本的,包括加开关和清理开关的成本、规则的制定和遵循等;

有时还需要从架构的角度考虑解决方案,比如将大的系统分解为一系列小的组件或服务,对不同修改频率的部分进行解耦,每个组件或服务独立开发和部署,这是处理复杂系统比较好的方式;

另外需要强调,主干开发模式非常强调代码提交习惯,包括频繁、有规律的代码提交(比如每人每天提交一次),而提交前需要进行充分的本地验证和预测试,以保证提交质量,降低污染主干代码的概率。

、使用高效的版本控制系统

版本控制系统是软件研发和运维过程中最常见的工具之一,经过多年的发展,涌现了很多优秀的开源工具或商业软件。目前公司内部正经历将已服务的多年的版本控制系统SVN加速转化为分布式版本控制系统Git的过程,这也与整个业界的趋势保持一致。

相比于SVN,Git在功能和效率方面拥有众多优势,比如对离线代码库的操作、本地分支的管理、本地多任务并行开发、分支创建/切换/合并/Diff的效率等等,大家应该都比较熟悉,我们就不详细展开介绍了。在这里我们重点强调在其之上的代码托管平台。

常见的Git代码托管平台包括Github、Gitlab等,基本都是依托于Git代码库的底层能力,在其基础上提供一套Web界面,以可视化的方式管理代码提交、拉分支等常用操作,并且提供wiki用于存储文档,提供集成的问题跟踪器等。当然,这里面还有一个我最看重的功能,就是对开发协作工作流的支持。近两年公司内部也基于业界实践和一些开源工具,开发了自己的Git代码托管平台,对于研发效率的提升作用是非常显著的。

我们再回头来看一下刚才介绍过的主干开发模式,在Git工具及其托管平台中的落地实例。

上图展示了在Git代码托管平台上,一种基于主干开发的协作流程。其中标记了十多个相关活动,分别由开发人员、测试人员和自动化执行的Job协作完成。首先是开发人员通过gitclone方式将代码检出到本地,并进行开发和提交(gitadd、git







































白癜风医院上海哪家好
白癜风容易治疗好吗



转载请注明地址:http://www.hnrjbl.com/jkhyjs/26837733.html
  • 上一篇文章:
  • 下一篇文章: