百度资深敏捷教练:深度解析持续交付之全面配置管理

发表于:2016-10-31 10:45

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:DBA+社群    来源:51Testing软件测试网采编

分享:
  2 、使用高效的版本控制系统
  版本控制系统是软件研发和运维过程中最常见的工具之一,经过多年的发展,涌现了很多优秀的开源工具或商业软件。目前公司内部正经历将已服务的多年的版本控制系统SVN加速转化为分布式版本控制系统Git的过程,这也与整个业界的趋势保持一致。
  相比于SVN,Git在功能和效率方面拥有众多优势,比如对离线代码库的操作、本地分支的管理、本地多任务并行开发、分支创建/切换/合并/Diff的效率等等,大家应该都比较熟悉,我们就不详细展开介绍了。在这里我们重点强调在其之上的代码托管平台。
  常见的Git代码托管平台包括Github、Gitlab等,基本都是依托于Git代码库的底层能力,在其基础上提供一套Web界面,以可视化的方式管理代码提交、拉分支等常用操作,并且提供wiki用于存储文档,提供集成的问题跟踪器等。当然,这里面还有一个我最看重的功能,就是对开发协作工作流的支持。近两年公司内部也基于业界实践和一些开源工具,开发了自己的Git代码托管平台,对于研发效率的提升作用是非常显著的。
  我们再回头来看一下刚才介绍过的主干开发模式,在Git工具及其托管平台中的落地实例。
  上图展示了在Git代码托管平台上,一种基于主干开发的协作流程。其中标记了十多个相关活动,分别由开发人员、测试人员和自动化执行的Job协作完成。首先是开发人员通过git clone方式将代码检出到本地,并进行开发和提交(git add、git commit),在经过了充分的本地构建和验证(Local Build)之后,将代码push到refs/for/master分支。代码变更的推送(Change Request)首先后触发一系列静态检查(比如代码规范、安全策略检查等),通过后进一步触发一个自动化测试的job(比如编译和单元测试),都通过后需要进行人工的Code Review。在人工评审确认代码无问题后,由具备模块Owner权限的Tech Lead一键式合入Master Branch。同样,代码的合入会触发主干上的一系列自动化测试Job,以及随代码提交或每日定时执行的集成测试作业。在准备发布时,会拉出发布分支进行发布前最后的测试。此时如果主干上提交了其它重要功能或者重大缺陷修复,则可以Cherry-Pick到发布分支上,最终从发布分支完成代码的发布操作。
  那么,Git及其代码托管平台在其中发挥哪些作用呢?我们来梳理一下:
  · 对于操作的简化。比如通过界面进行代码库的创建、权限的设置、代码库的搜索、一键拉分支、一键合并代码、比较代码、冲突显示和解决等;
  · 对于代码提交规则的设置和校验。比如可以设置提交前必须经过代码规范检查,提交后必须经过自动化测试验证和Code Review检查等;
  · 与研发相关系统的打通。打通Code Review系统、需求管理系统(代码与需求建立映射关系)、编译系统(用于获取代码并编译和打包)、自动化测试系统等。系统的打通非常重要,比如Code Review系统如果不能和代码托管平台有机整合,相关评审制度就很容易坚持不下来。Google对代码评审要求就非常严苛,他们的做法就是通过系统无缝对接,从技术上保证了只有评审通过的代码才能被提交进代码仓库。
  · 对于分支的关系智能计算和提示。比如计算多个分支之间的版本差异和代码差异,以及在主干版本领先于发布分支时,提示分支需要合并最新主干代码后才能发布等;
  · 还有最重要的,对于协作流程的支持和定制。以上展示了一种主干开发模式的协作工作流,实际项目中常用的还有Git Flow工作流、Pull Request工作流、Feature Branch工作流等等,这些不同的工作流也许是基于某些特定场景的最优选择,那么最好都可以在Git代码托管平台上进行支持和定制。
  通过以上分析可以看出,使用高效的版本控制系统,配合可进行协作流程支撑的代码托管平台,对于配置管理的优化、让复杂场景以最小代价实现,其作用是非常显著的。
  3 、对构建产物及其依赖进行管理
  持续交付强调要对所有内容进行版本控制,除了对源代码、测试代码等配置项做好管理,还有一点非常重要,就是对构建产物进行有效管理。构建产物一般是指在编译或打包阶段,生成的可用于部署的二进制包。一般情况下,我们不推荐将构建产物存放在版本控制库中,因为这样做效率较低也确实没有必要。通常我们使用的开源制品库包括Nexus或Artifactory,或者自开发的制品库(最简单的可能就是一个共享存储),通过版本标识等信息对构建产物进行管理。
  制品库在应用时有一些有用的实践:
  在编译阶段创建二进制部署包,并上传到制品库。为了保证一致性,二进制部署包一般只在编译阶段生成一次,后面的所有测试和部署上线都复用这个包,而不要重复编译;
  制品库可用来管理依赖,比如Java领域的Maven,Python领域的Pypi等,都提供了全面的依赖管理机制,可以按GAV三元组(groupId/artifactId/version)唯一标识和引用一个对象,这样当构建项目时,会自动先下载指定的依赖;
  制品库可以按用途分为临时制品库和正式制品库,其中的制品保存周期可以不同。一般来讲,在交付流水线中进行发布时,会执行以下三个动作:(1)制定发布的四位版本号;(2)将当前代码按版本打Tag;(3)将二进制包从临时制品库迁移到正式产品库。
  四、应用的配置管理
  1 、部署包的结构和应用配置
  为了能够交付可正常运行的系统,我们需要把一切应用程序需要的内容进行标准化,并且注入到部署包中。作为应用程序正常运行的关键因素,应用的配置与程序文件、数据和各类部署和控制脚本缺一不可。
  上图展示了某种部署包的结构。如果产品线需要部署的服务器规模比较大,我们就需要通过标准化部署包的封装,帮助我们实现部署过程的全自动化。比如大家熟悉的Docker,它为什么能够做到build once,run anywhere?本质上就是做了封装,把应用程序和相关依赖打在一起,生成一个镜像去部署。我们可以参考这种方式,把部署包设计为一个全量包,它不仅包含了二进制的可执行程序文件,还包含应用的配置、模块数据,也同时包含运行时依赖。我们把它打包一起,这样才能做到在任何一个标准化的环境里面,能够快速的将应用部署起来。另外,在部署包中还需要提供一个稳定的控制接口,用来描述程序怎么启动、怎么停止、怎么重启,怎么监控健康状况,告知部署系统如何进行部署和运维等。
  接下来我们重点谈一下应用配置相关的问题。
  2、应用配置的注入方式
  我们经常遇到的问题是,应用配置在不同环境中是不同的,比如数据库的IP地址和端口、是否打开Cache、加密所用的密钥等,这些参数与应用程序逻辑无关,而只与环境相关。那么同一个部署包如何适配不同环境所需的应用配置呢?为了解答这个问题,我们先来看一下应用配置信息的几种注入方式。
  如上图所示,应用配置的注入一般有三种方式:
  · 打包时注入
  在打包的时刻,构建脚本可以将配置信息与二进制文件一起,注入到部署包中。比如J2EE规范中就要求配置信息与应用程序要一起打包到war或ear包中。
  · 场景: 少量静态配置文件,或配置每次随二进制程序变更
  · 优点: 打包和部署的过程比较简单,不同环境使用特定的部署包
  · 缺点:环境、应用、配置紧耦合,灵活性低
  · 部署时注入
  在进行部署时,部署脚本获取基础配置以及不同环境特定的配置项,动态生成每个环境所需的配置信息。相当于基于配置模板文件,在部署时再实例化为将要部署应用的具体环境的配置。
  场景: 大量的配置项,一些配置项在不同环境中存在差异
  优点: 可以使用部署脚本或工具,动态生成特定环境配置信息
  缺点:需要维护应用与配置版本的匹配关系,增加了复杂度
  · 运行时拉取
  在应用应用启动或运行时,通过外部的配置服务拉取应用配置(如通过REST风格的接口)。现在很多使用容器部署的微服务架构系统,配置中心或配置服务都是其非常核心的组件之一。
  场景: 频繁变更配置项,或者需要动态加载应用配置
  优点: 部署包与配置彻底解耦,具备较高的灵活性
  缺点: 需要考虑配置中心的高可用性和配置变更的原子性
  从持续交付的理念来看,不推荐在打包时注入配置的方式,因为我们希望在不同的环境中使用相同的部署包,以确保发布的版本就是我们充分测试过的。在一些团队中曾经发现,为了适配测试环境,测试人员使用源代码自己进行编译和打包,那么即使这个版本测试通过了,也无法确保生产环境部署的应用版本是没有问题的。所以我们更倾向于对应用配置单独进行版本控制,并独立于部署包之外进行管理。
32/3<123>
重磅发布,2022软件测试行业现状调查报告~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计

法律顾问:上海漕溪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2023
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号