2019独角兽企业重金招聘Python工程师标准>>>
随着云和容器技术的发展,大家对DevOps和CI/CD的重要性有了更深入的认识。今天我们就讨论一下架构设计如何更好的支持CI/CD。
什么是持续集成,交付和部署(CI/CD)
Martin Fowler 和 Kent Beck 首次提出 Continuous Integration (简称:CI),将之描述为:持续集成是一种软件开发实践:许多团队频繁地集成他们的工作,每位成员通常进行 日常集成,进而每天会有多种集成。每个集成会由自动的构建(包括测试)来尽可能快地 检测错误。许多团队发现这种方法可以显著的减少集成问题并且可以使团队的开发更加快捷。
持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,我们可以确定新代码和原有代码能否正确地集成在一起。
持续交付(简称:CD )
持续交付在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境的「类生产环境」(production-like environments)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的 Staging 环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境中。
持续部署 (居然简称也是CD )
持续部署则是在持续交付的基础上,把部署到生产环境的过程自动化。
什么是成熟度模型
软件开发者对CMM(Capability Maturity Model 能力成熟度模型)这个词应该不陌生,记得我毕业后的第一家单位最早搞ISO9000,后来又要上CMM,后来评了个CMM三级,据说CMM五级的公司都牛B的不行。我一直对这种东西不太感冒,摩托罗拉据说就是CMM五,然而... ...
西方人的思维喜欢搞标准化,软件成熟度模型就是一种标准化的模型,把软件组织分成五个等级,一级为初始级,二级为可重复级,三级为已定义级,四级为已管理级,五级为优化级。现在已经没有什么软件企业还搞这个CMM了。
不过,这个成熟度模型还是有人在用,这不,有人提出了持续交付的成熟度模型。
持续交付的成熟度模型
Andreas Rehn,Tobias Palmborg,Patrik Boström提出了持续交付的成熟度模型,针对文化和组织,设计和架构,构建和部署,测试和验证,以及信息和报表五个维度分成了基本(Base),起步(Beginner),中等(Intermediate),高级(Advanced),专家(Expert)五个等级。
持续交付和架构设计
我们今天主要看看架构的设计对持续交付的影响,先来看看模型是如何定义的。
对于大多数的组织来说,为了支持持续交付而重新设计架构并不是一个吸引人的选项,所以该模型可以用来评估组织究竟何种境地。下面就是该模型对五个不同等级关于架构设计的描述。
基本(Base)
该组织通常在开发,构建,发型一个或者多个具有巨石架构的旧系统。拥有复杂的技术栈,但已经开始考虑统一技术和平台。
起步 (Beginner)
在这个等级上,巨石结构的系统被分为小的模块。这样的小模块更利于开发,构建和部署。但是这些模块还不能像独立组件一样的发布。这样做很自然的导致使用API来描述内部的依赖关系,并系统的管理第三方的库。在这个等级,通常会使用版本控制来记录和管理变化。
中等 (Intermediate)
达到中等水平需要有一个坚实的架构基础来支持持续交付,需要采用抽象分支和其它特征隐藏来最小化代码库的分支数量。模块进化为自描述和独立部署的组件。在这个阶段,组织很自然地会把分散的,随意管理的应用的运行配置用版本控制系统进行管理,并把它们看作是代码的一部分。
高级 (Advanced)
在这个等级,整个软件系统被划分为自包含的组件并严格采用API来进行组件间的通信,这样每个组件才能独立的部署和发布。每个组件都是自包含的,可发布的,具有独立商业价值的单元,该单元可以有很小和很频繁的发布周期。发布新的功能,监视并验证商业价值变的很容易。通过应用收集可视化的业务指标是该阶段软件设计和架构要考虑的一个重要部分。
专家 (Expert)
在专家级,组织进一步的进化基于组件的架构,把基础设施作为代码以尽可能的减少共享的基础设施,并绑定到应用组件。结果就是系统是可已通过源代码控制系统重建,从操作系统直至应用。这样做可以减少大量的复杂性和其它工具以及技术的开销,例如灾备系统来保证生产环境是可以随时重建的。和虚拟化技术一起,这样做对于手工搭建测试和生产系统带来了很多的灵活性。
通过以上描述(翻译水平有限,请谅解),你可能还是不能明白这尼玛究竟说了些什么,我来解读一下:
- 微服务 (Micro Service)
随着成熟度的提高,软件架构从巨石架构,到模块化,到组件化,到最终组件通过标准API通信的类似微服务的架构。要做到持续交付,最好把复杂的软件分成独立的服务,每一个服务都可以独立运行。就像凯文凯利在失控一书中提到的,去中心化的分布系统,每一个组件都能独立运作,都很简单,组合在一起,变的无比牛B。生命体,计算机,无不是这样的系统。 - 减少分支 (Minimal Branch)
在我们日常的开发中,软件的分支通常非常多,如下图:
持续交付的高成熟度表现为尽可能少的分支。最理想的情况,开发直接在Release分支上,提交代码后马上在测试环境下部署测试,测试通过,直接部署到生产系统。这样做,对自动化测试要求非常的高。 - 配置即代码 (Configuration as Code)
应用的配置文件必须提交到代码库中管理。这个似乎和架构关系不大。 - 收集业务指标 (Push Business Metrics)
收集业务指标是持续交付的一个重要环节,当我的一个新的代码提交后,业务指标直接反馈给相应的决策者,例如性能是变好还是变坏,用户是变多还是变少,等等。所以在软件设计时,如何收集这些业务指标,是需要考虑的。 - 基础设施即代码 (Infrastructure as Code)
容器技术对于持续交付的影响可以说是颠覆性的,这里基础设施即代码,大家可以很自然的联想到容器,以前我们要测试,或者部署某个应用,需要把该应用运行在不同的硬件和操作系统下,在新的交付模式中,应用是和它所在的基础设施也就是容器一起交付的。以前对于不同的应用,有不同的交付产物,可能是可执行文件,可能是war包,可能是安装程序,在容器时代,交付物变成了容器镜像(image),于是基础设施变成了代码的一部分(使用Dockerfile来构建镜像)。
参考文献
- http://tracks.roojoom.com/r/35499
- https://www.infoq.com/articles/Continuous-Delivery-Maturity-Model
- http://info.thoughtworks.com/rs/thoughtworks2/images/Continuous%20Delivery%20_%20A%20Maturity%20Assessment%20ModelFINAL.pdf