持续交付

软件交付有什么问题?

常见的发布反模式

(一)手工部署软件

手工部署软件的特征及其明显。
1、一份非常详细的文档,该文档会描述执行步骤及每个步骤中容易出错的地方
2、以手工测试来确认该应用程序是否正确运行
3、在发布时,常常会修改一些在发布过程中的发现的问题
4、如果是集群环境部署,经常出现集群中各环节配置不一致
5、发布需要较长的时间(超过几分钟)
6、发布结果不可预测,常常不得不回滚或遇到不可预见的问题
7、需要具备相当程度的专业知识,而且过分依赖于技术专家,如果人员流动,会造成很大的困难

(二)开发完成之后向类生产部署

 在这个模式下,当软件第一次被部署到准生产环境时,就是大部分开发工作完成时,至少是开发团队认为“该软件完成了”。
这种模式经常出现的情况如下:
1、如果测试人员一直参与了在此之前的过程,那么他们已在开发机器上对软件进行了测试
2、运维人员接触新应用程序较晚
3、准生产环境比较昂贵,所以权限限制严格,操作人员无权对该环境进行操作,也有可能环境没有按时准备好,甚至也可能根本没人去准备环境。
4、开发团队将正确的安装程序、配置文件、数据库迁移脚本和部署文档一同交付给那些真正执行部署任务的人员,而所有这些都没有在准生产环境或试运行环境中进行过测试
5、开发团队和真正执行过部署任务的人员之间的协作非常少,交付后的协作成本非常高

(三)生产环境的手工配置管理

 很多组织通过专门的运维团队来管理生产环境的配置。如果需要修改一些东西,比如修
改数据库的连接配置或增加应用服务器线程池中的线程数,就由这个团队登录到生产服务器上手工进行修改。
 这种模式的特征如下:
 1、多次部署到试运行环境都非常成功,但当部署到生产环境时就失败
 2、集群中各节点的行为有所不同。例如,与其他节点相比,某个节点所承担的负载少一些,或者处理请求的时间多花一些
 3、运维团队需要较长时间为每次发布准备环境
 4、系统无法回滚到之前的某个配置,包括操作系统、应用服务器、数据库系统、Web服务器或其他基础配置
 5、集群中的某些服务器的操作系统、第三方基础设置、依赖库的版本或补丁不一致
 6、直接修改生产环境上的配置来改变系统配置

(四)为什么要做自动化部署

1、部署过程不可重复也不可靠,在调试部署错误的过程中就会浪费很多时间
2、自动化部署协作效率更高
3、自动化部署的专业强度没有太严重,搭建好的流水线一般来说只需要点击部署即可
4、使用相同的配置在各种环境中,降低配置丢失或不一致的风险
5、发布周期短,问题处理快
6、降低协作成本,提高交付效率

软件开发的目标

作为软件行业从业人员,我们的目标就是尽快的向用户交付有用的可工作的软件,找到一种高效、快速、可靠的方式交付高质量且有价值的方法。
为了达到这些目标,我们需要频繁且自动化的发布软件。
	1、由于软件本身、系统配置、环境以及发布过程的不同,每次做完构建、部署、测试、发布后,其结果可能都会有所不同。而且由于每个操作都是手工操作,出错的机率变大
意味着整个发布流程都无法得到应有的控制来保证高质量,而这些活动如果是自动化的,就会有规律可循,能快速地定位风险以及减少操作风险。
	2、自动化可以频繁的做,频繁地发布,每个发布版本之间的差异非常小,发布风险因此比较低,回滚更容易,还能加快反馈速度,更好地跟客户说明情况。
对于自动化发布来说,反馈至关重要,反馈分成三个标准:
	1、无论什么样地修改都应该触发反馈流程
	2、反馈应该尽快发出
	3、交付团队必须接收反馈,并依据它作出相应地行动

使用自动化发布地方法主要是创建一个发布流程,这个流程可重复,可靠性强且可预见,大大地缩短了发布周期,使新增功能可以更早地与用户见面。
自动化地收效体现在减少错误、缓解压力、部署的灵活性、每次提交代码都可以产生一个可发布的版本。

	减少错误:自动化部署的配置文件在各个环境都是一致的,不会出现人工配置出错的情况。
	缓解压力:生产上线时发布时间大大减少,不用通宵熬夜加班解决部署问题
	部署的灵活性:想部署什么版本就部署什么版本,版本的可追溯性强
	快速部署版本:一天可以进行多次代码集成、版本发布

软件交付的原则

1、为软件地发布创建一个可重复且可靠地过程
2、将几乎所有事情自动化
3、将所有地东西都纳入版本控制
4、提前并频繁做让你感到痛苦地事
5、内建质量
6、“DONE"意味着”已发布“
7、交付过程是每个成员地责任
8、持续改进

				图 1-1 一个简单的部署流水线
编译,单元测试,分析,构建
演示,探索性测试
提交阶段编译
自动化验收测试
自动化容量测试
手工测试
发布

配置管理

	定义:配置管理是指一个过程,通过该过程,所有与项目相关的产物,以及它们之间的关系都被唯一定义、修改、存储和检索。
 	版本控制系统(也被称为源代码控制管理系统或修订控制系统)是保存文件多个版本的一种机制。
当修改某个文件后,你仍然可以访问该文件之前的任意一个修订版本。
	版本控制的目的可以分成两个:
	1、保留每个文件的所有版本的历史信息,并使之易于查找。
	2、让分布式团队可以愉快的协作

版本管理

对所有内容进行版本控制

版本控制不仅仅针对于源代码,每个与所开发的软件相关的产物都应被置于版本控制之下。除了存储源代码和配置信息,还包括应用服务器、编译器、虚拟机以及其他相关工具的二进制镜像也需放在版本控制库中。
版本控制策略在控制和行为保障方面建立了基础。在这种严格配置管理策略约束下的系统,根本不存在整个流程的后期还会出错的可能性,可以确保在保证存储库完整性的情况下,我们在任何时候都能拿到应用软件的一个可工作的版本。给与足够的安全保证。

频繁提交代码到主干

使用版本控制事,有两点至关重要。
1、频繁的提交代码才可以享受版本控制所带来的众多好处,比如轻松回滚到最近某个无错误的版本
2、一旦将变更提交到版本控制库中, 团队的所有人都能看到这些变更
频繁的提交代码,频繁的集成代码部署应用,可以减少因重构而引起的大规模合并导致冲突的可能性。

使用意义明显的提交注释

每个版本管理工具都提供“写注释功能”,注释常常被忽视,我们不常在项目中发现不写注释,以及乱写注释的现象。这种现象在没有bug的前提下其实并不会带来什么,当发现缺陷,特别是时间久远一些,就会更难找到出错的位置。时间成本大大增加。

依赖管理

软件项目中,最常见的外部依赖就是其使用的第三方库文件,以及该软件需要用到的正由其他团队开发的模块或组件间的关系。库一般是以二进制文件的形式部署,不会被你自己的团队更改,而且也很少更新

不同情况下的配置

1、在生成二进制文件时,构建脚本可以在构建时引入相关的配置,并将其写入新生成的二进制文件
2、在打包时将配置信息一同打包到软件中
3、在安装部署程序时,部署脚本或安装程序可以获取必要的配置信息,或者直接要求用户输入这些配置信息
4、软件在启动或运行时可获取配置

环境管理

每个应用程序都依赖于硬件、软件、基础设施以及外部系统才能正常工作。这些内容都被称作应用程序的环境。
环境管理的原则是:环境的配置和应用程序的配置同样重要
不良的环境管理可能带来以下问题:
1、配置信息的集合非常大
2、一丁点变化就能让整个应用坏掉,或者严重降低它的性能
3、一旦系统出现点问题。需要资深人员花费不确定的时间来找到问题根源并修复他
4、很难准确地再现那些手工配置的环境,因此会给测试验证带来很大困难
5、很难维护一个不使用配置信息地环境,因此维护这种环境下地行为也很难,尤其是不同地节点有不同的配置时
环境管理地关键在于通过一个全自动过程来创建环境,使创建全新地环境总是要比修复已受损地就旧环境容易。重视环境的原因有:

1、可以避免知识遗失问题
2、修复某个环境可能需要花费数小时的时间。所以我们最好在可预见的时间内重建环境,,并将它恢复到某个已知的状态下
3、创建一个和生产环境相同的测试环境是非常必要的,这样,配置问题更容易被在早期发现

需要考虑的环境配置信息有:

1、环境中各种各样的操作系统、包括其版本、补丁级别以及配置信息
2、应用程序所依赖的需要安装到每个环境中的软件包,以及这些软件包的具体版本和配置
3、应用程序所依赖的所有外部服务,以及这些服务的版本和配置信息
4、应用程序正常工作所必需的网络拓扑结构
5、现有的数据以及其他相关信息(比如生产数据等)

高效配置管理策略的原则

1、将二进制文件与配置信息分离
2、将所有的配置信息保存到一处

持续集成

持续集成的先决条件

准备工作

1、版本控制,与项目有关的所有内容都必须提交到一个版本控制库中,包括产品代码、测试代码、数据库脚本、构建与部署脚本,以及所有用于创建、安装、运行和测试该应用程序的东西。
2、自动化构建,要能在持续集成环境中以自动化的方式来执行整个构建过程,以便出现问题是能够审计;将构建脚本与代码库同等对待;使理解、维护和 调试构建过程更容易,并有利于和运维人员更好地协作

一个基本地持续集成系统

持续集成不是工具,是一种实践。你可以通过选择相应地工具来实现它,选择并安装好持续集成工具之后,需要进行一些配置。比如让它知道哪里去寻找源代码,必要时运行哪个脚本进行编译,并执行自动化提交测试,以及一旦最新地提交破坏了应用程秀,通过哪种方式通知你。

持续集成地前提条件

频繁提交

频繁提交代码到版本控制库对于持续集成来说是至关重要地。每天至少提交几次代码。

创建全面地自动化测试套件

如果没有一系列全面的自动化测试,那么构建成功只意味着应用程序能够编译并组装在一起。有三类测试我们会用在持续集成中,分别是单元测试、组件测试和验收测试。

保持较短的构建和测试过程

长时间的构建和测试过程中, 容易遇到一些麻烦。
1、大家在提交代码之前不愿意在本地环境进行全量构建和运行测试,导致构建失败的几率越来越大。
2、持续集成过程需要花太长时间,从而导致再次运行构建时,该构建会包含很多次提交,所以很难确定到底是哪次提交破坏了本次构建。
3、大家的提交频率会随着一次构建和测试时间过长而减少

管理开发工作区

开发环境的管理对于保证开发人员的开发效率与明晰思路来说是特别重要的。
他们通常应该在自己的开发机上, 能够运行构建、执行自动化测试、以及在其可控的环境是部署其开发的应用程序。只有在特殊的情况下,才会使用共享环境开发。在本地开发环境上运行程序时,应确保所使用的自动化过程与持续集成环境中的一致,与测试环境中的也一致,且生成环境也是一样的。

必不可少的实践

1、构建失败之后不要提交新代码
2、提交前在本地运行所有的提交测试,或者让持续集成服务器完成此时
3、等提交测试通过后再继续工作
4、回家之前,构建必须处于成功状态
5、时刻准备着回滚到前一个版本
6、在回滚之前要规定一个修复时间
7、不要将失败的测试注释掉
8、为自己导致的问题负责
9、测试驱动的开发

部署流水线

什么是部署流水线?
部署流水线是指软件从版本控制库到 用户手中这一过程的自动化表现形式,对软件的每一次变更都会经历一个复杂流程才会发布。这一流程包括编译构建,以及后续不同阶段的测试与部署。部署流水线是对这一流程的建模,在持续集成和发布管理工具上,它体现为支持查看并控制整个流程,包括每次变更从被提交到版本控制库开始,直到通过各类测试和部署,再到发布给用户的过程。

部署流水线地目的是,让软件交付过程中地每个人都能够看到每个构建版本从提交到发布地整个过程,大家可以看到哪次修改破坏了应用程序,哪次修改可以作为候选发布版本进入到手工测试环节或发布环节。

部署流水线的相关实践

1、只生成一次二进制包
2、对不同环境采用同一部署方式
3、对部署进行冒烟测试
4、向生产环境的副本中部署
5、每次变更都要立即在流水线中传递
6、只要有环节失败,就停止整个流水线

提交阶段

提交阶段,我们需要做以下几件事。
1、编译代码(如果所用开发语言需要的话)
2、运行一套提交测试
3、为后续阶段创建二进制包
4、执行代码分析来检查代码的健康状况
5、为后续阶段做准备工作,比如准备一下后续测试所用的数据库‘

发布准备

每次向生产环境发布时都有业务风险,为了缓解这一类风险,我们只需要把这个发布缓解当成部署流水线的一个自然结果就好。
1、让参与详谬交付过程中的人共同创建并维护一个发布计划(包括开发人员和测试人员,以及运维人员,基础设施和支持人员)
2、通过尽可能多的自动化过程最小化人为错误发生的可能性,并从最容易出错的环节开始实现自动化
3、在类生产环境中经常做发布流程演练,这样就可以对这个流程及其所使用的技术进行调试
4、如果事情并没有按计划执行,要有撤销某次发布的能力
5、作为升级和撤销过程的一部分,制定配置迁移和数据迁移的策略

在成功的基础上构建

当一个候选发布版本能够部署到生产环境时,我们可以确定:
1、代码可以编译
2、代码能够按开发人员的预期运行,因为它通过了单元测试
3、系统能够满足分析人员或用户预期,因为它通过了所有的验收测试
4、基础设施的配置和基线环境被恰当地管理了,因为应用程序在模拟地生产环境上通过了测试
5、系统所有地正确组件都准备就绪
6、部署脚本也是可以正常工作地,因为在该版本到这一阶段之前,部署脚本至少在开发环境、验收测试环境以及测试环境中用过
7、我们需要部署地所有内容都在版本控制库中,而且不需要手工干预,因为我们已经部署这个系统好几次了

实现一个部署流水线策略

1、对价值流建模,并创建一个可工作地简单框架
2、将构建和部署流程自动化
3、将单元测试和代码分析自动化
4、将验收测试自动化
5、将发布自动化

流行的构建工具

Make

一种强大的产品导向的构建工具,能在单词构建中追踪依赖关系,还能只构建那些受到本次修改影响的组件。
随着应用程序复杂程度和组件之间依赖关系的增加,这种复杂性会让Make变得越来越难以调试。另一个缺点是,它依赖于shell做所有的事情,因此,makefile必须与操作系统绑定。由于Makefile是一种外部的DSL(Domain-Specific Language 领域特定语言),并不提供对核心系统的扩展能力。在无法使用Make的内部数据结构的前提下,所有的扩展都必须重建公共解决方案。
Make程序本身所用的声明式编程模型并不为大多数开发人员所了解,因此Make很少在商业应用中被用作主要的构建工具
很多C/C++项目中,开发人员更倾向于SCons,而不是Make.SCons本身和它的构建文件都是用Python写的,还有许多非常有用的特性,比如支持Windows和并行构建。

Ant

Ant是一个任务导向的构建工具。Ant的运行时组件也是用java写的,但Ant脚本是用XML书写的一种外部DSL。这种结合是Ant具有了强大的跨平台能力,是极其灵活和强大的系统,因为Ant的任务几乎可以让你做任何想做的事情。
Ant也有一些缺点:
1、使用XML书写构建脚本,但XML脚本既不简洁,又不易阅读
2、Ant是一个贫血领域模型。任务上没有真正的领域概念,需要花费大量的时间为编译、生产jar、运行测试等编写样版文件
3、Ant是声明式语言,而非命令式语言,只提供了少量的命令式标签给用户使用
4、对新手用户来说,很难理解
5、没法回答“运行了多少个测试”以及“它们花了多少时间”等问题,为了实现这种功能,只能找个工具把这些信息输出到命令行窗口中,然后对其进行解析,或者写JAVA代码做个钩子,放在Ant中。

Maven

Maven有一种“惯性胜于配置”的原则,只要项目按照Maven指定的方式进行组织,他就几乎能用一条命令执行所有的构建、部署、测试和发布任务,却不用写很多行的XMl。
Maven能自动管理Java库和项目间的依赖,而这正是大型JAva项目的痛点。Maven还支持一种复杂且严格的软件分区方案,使你能将复杂的解决方案分解成较小的组件。
Maven有三个比较大的缺点:
1、如果项目没有按照Maven规定的结构和生命周期来组织的话,你很难使用Maven
2、也需要XML写的外部DSL,扩展的前提是要用插件
3、在默认配置中,是自动更新,Maven每次运行时都会尝试更新自己,而这种插件的自动升降级有可能导致不可预期的失败。Maven的库和依赖管理允许在多个项目之间使用组件的快照,如果使用这种快照依赖的话,就很难重新某次构建。

Rake

Rake和Make一样是产品导向的工具,但也可以用作任务导向的工具。Rake也只能理解任务和依赖。Rake是Ruby开发的,可以用Ruby的API来执行任何任务,可以实现用通用编程语言的所有本地化功能的场景。
Rake的两个缺点:
1、平台上装有适当的Ruby运行环境
2、组合使用RubyGrems

Buildr

Buildr建立在Rake上,Rake可以做的事情,它都能做。而且,也是Maven的简易替换,用和Maven一样的惯例,包括文件系统布局、产物规范和仓库。还可以使用Ant的任务,却无需配置。利用Rake的产品为导向的架构做增量构建。比Maven运行快,且与它不同,Buildr定制任务或创建新任务是极其容易的。

Psake

PowerShell写的内部DSL,提供了面向任务的依赖网络。

构建部署脚本化的原则与实践

1、为部署流水线的每个阶段创建脚本
2、使用恰当的技术部署应用程序
3、使用同样的脚本向所有环境部署
4、使用操作系统自带的包管理工具
5、确保部署流程是幂等的
6、部署系统的增量式演进

构建和部署的一些方案

1、总是使用相对路径:构建中最常见的错误就是默认使用绝对路径,这会让构建流程和某台特定机器的配置形成强依赖,从而很难被用于配置和维护其他服务器
2、消除手工步骤
3、从二进制包到版本控制库的内建可追溯性
4、不要把二进制包作为构建的一部分放在版本控制库中
5、“test”不应该让构建失败:这样做的理由是,可能有几个测试任务,如果第一个测试失败了,后续的测试就得不到验证
6、用集成冒烟测试来限制应用程序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值