HudsonDOC第1页共23页1互联网行业应用持续集成(CI)实践吴峻申修改记录HudsonDOC第2页共23页2目录HudsonDOC第3页共23页31互联网行业软件开发特点和现状简介当前中国互联网行业是一个竞争力非常强也压力非常大的行业。一个互联网公司如果不时刻拿出让广大用户喜闻乐见,易于使用的软件产品,其命运必然是被这个行业所淘汰。而在互联网软件产品开发中,如果没有良好的管理和高效率的工具来帮助开发和测试,那么整个项目团队就会处于无序混沌的状态。以这样的状态是无法产生之前所述的那种软件产品。本文所记述的持续集成就是为了避免这种开发测试情况在互联网软件行业中蔓延而引入的一种项目管理方法实践和使用工具。其目的也是为了进行快速软件开发,制造高质量的软件产品。互联网应用还有一个极其有趣的特点就是“永远都是beta版”。一万个人对这个特点有一万种见解和看法。其实这个特点告诉我们在互联网行业,客户是永远不会满足已有软件产品目前所具有的功能。他们总是希望能满足他们个人自己的需求。为了争取让用户体验程度更加好,也为了提高网站用户粘度,互联网行业公司必需拥有一套完整的解决方案和实践集合来实现这个目的,而持续集成也属于这样的方案。因为面对客户提出的各种新功能,新应用,开发人员需要即时相应这些复杂而又详细的需求,并更好更快的实现这些需求。而实现需求后,如何保证是否很好满足客户需求,是否让客户感觉“酷”,是否这样实现需求方式是最快最好的?这就需要持续集成能来帮忙了。简单来说持续集成在这里就是提供了一种“保障体制”,防止了很多软件开发中的风险发生,也进一步推动了提高用户体验度和用户粘度的实践流程的发展。2持续集成实践介绍2.1为什么我们要进行持续集成?持续集成不是一项软件开发实践,而是多项软件开发实践的集合。团队在尝试引入这些开发实践时,不可避免要遇到一个问题:为什么要持续集成?如果不能很好地理解为什么,持续集成可能会进入误区,不能带来期望的效果。早期的软件开发模式是由程序员负责编写不同的模块,在软件项目完成之前,一次性的把各个模块集成在一起,再进行测试。我们称这种集成方式为“big-bang”的集成方式。使用该种集成方式的项目团队把软件集成安排在开发阶段的后期,一般是应用“瀑布式(Cascade)”开发模式。在项目后期才开始对软件进行集成,会为项目引入很多的未知因素和巨大风险--程序员往往发现越来越多的Bug等待他们去修复。这种集成方式很有可能会威胁到软件项目的成功。随着市场竞争的日益激烈,对软件产品的发布要求越来越高、越来越频繁,这种“big-bang”的集成方式已经不能满足开发团队的需求。取而代之的持续集成的开发方式“Continuousintegration”。持续集成可以有效地解决软件开发过程中的许多问题,可以有效的确保软件质量,减小项目的风险,使得软件开发团队从容面对各种各样的变化。在开发过程中如何提高项目可见性?项目的进度如何?哪些需求已实现?哪些代码已测试?代码的品质如何?持续集成及时呈现各种分析报告,让开发团队和管理层了解项目的真实状况,从而制定正确的决策。“不识庐山真面目,只缘身在此山中”的感觉一去不复返。一般来说,最成功的人拥有最好的信息。因此为什么要持续集成?就是因为持续集成将改善软件的质量,降低风险,使软件开发HudsonDOC第4页共23页4变得更有效率,让大家能够“愉快工作,幸福生活”,而不是“加班工作,维持生活”.这不是唯一的标准答案,每个团队都可以思考讨论,得到属于自己的答案。2.2持续集成由那些实践组成?前文已提及持续集成是多种软件开发实践的集合,那么本节对这些开发实践做进一步的说明,能够让我们更加清晰认识进行持续集成的目的。数据集成数据是所有IT系统的核心,所有的架构都建立在数据的基础之上,其目的都是为了更好地处理数据。由于数据如此重要,所以我们派专人来负责管理和维护,这就是DBA.不幸的是,DBA与程序员似乎来自于不同的文化,他们讲的不是同一种语言。结果常常导致程序员基于自己对数据库的假设来开发程序,到了项目的后期才与真实数据库进行集成。这种假设会带来很大的集成和部署风险,影响代码的品质,可能引起大量的返工。对于针对已有数据集的开发,持续集成强调尽可能早地与实际数据集成,例如可以通过数据库复制,在一个几乎与生产环境一样的开发环境中进行开发。此外,DBA可以与开发团队密切配合,双方分享观点与经验,使数据库的组织方式也能够根据新的业务需求与时俱进。如果项目要开发一个全新的应用,还没有数据集存在,怎么办?办法很简单:一、尽早得到真实的数据集。二、随着开发团队对问题域的理解不断加深,应用功能的不断实现,让数据的组织方式也不断优化。静态代码检查不同的人写的代码,其品质差异比较大。相同的人在不同时间写的代码,其品质也可以有相当的差异。为此,人们设计了代码评审活动,来提高代码品质。极限编程则通过结对编程的实践,将代码复查工作扩展到开发的每一分钟。这样做代价不菲。当然,根据克劳斯比的观点,以这样的代价换取高品质的产品,总的来说还是值得的。但是人们总是在想,如果能够降低检查的成本,又能够获得检查的好处,岂不美哉?编码标准就是一个典型的例子。相信每一个严肃的开发机构都不会不提编码标准,但是检查代码是否符合编码标准却是一件耗时耗力的事情,这导致了在许多项目中,编码标准有名无实。自动化的代码检查工具承担了这项繁复的工作。像CheckStyle这样的工具,能够自动检查代码是否符合编码标准。项目以能够承受的代价,满足了编码标准。程序员也在这种检查中不断提高,养成良好的编码习惯。静态代码检查还能做更多的事。出于种种原因,我们希望代码能够做到“低耦合,高内聚”.像PMD这样的代码依赖关系检查工具能帮助我们发现不正当的依赖关系。重复的代码是品质的大敌,PMD还能找出重复的代码。人们在使用某种编程语言时,会有一些容易犯的错误,像FindBugs这样的工具能够帮助我们找出这些错误。静态代码检查不是要完全替代评审活动,但它能够让我们从繁复的低创造性活动中解放出来,专注于创造性的思维和活动。工具的归工具,人的归人。自动化测试利用现有的技术,我们可以用能够承担的成本,将许多的测试自动化。这些自动化测试包括单元测试、集成测试、系统测试、验收测试、压力测试等。而通过持续集成来持续进行HudsonDOC第5页共23页5自动化测试,将带来许多好处。自动化测试减轻了开发团队的压力,让大家对系统有信心,使工作的气氛变得更轻松。有了自动化测试的保护,开发者也敢于不断对系统进行改进,添加新的特征和改进代码品质。当系统有机会越来越好时,我们才可能创造出了不起的软件。自动化测试降低了测试和修改的成本。错误越早发现,更正它的成本就越低。自动化测试加速了开发/测试循环,从而使修正错误的成本降低。容易测试的系统就容易增强和维护,难测试的系统就难增强和维护,不可测试的系统基本上可以排除在我们的考虑之外。测试成本低的系统才是开发维护成本低的系统。自动化测试报告了系统的真实进度。哪些需求已实现?现有的架构和实现是否能满足性能需求?自动化的验收测试和压力测试会告诉我们准确的答案。在许多情况下,我们都有理由让需求可测试,让测试能够自动执行。自动化部署。系统能否部署到目标生产环境?是否需要进行一些数据迁移和应用升级?配置文件是否正确?理解这些问题的最好方式就是将部署过程自动化。通过向近似于生产环境的目标环境持续部署,确保部署过程没有问题。在自动化部署成功后,再对部署好的系统执行验收测试和压力测试。持续部署可以尽早发现部署过程中的问题,降低系统上线时的风险。2.3持续集成能够解决什么?持续集成在现代软件开发中扮演着非常重要的角色。使用持续集成策略的团队,可以发现持续集成可以为软件开发带来如下好处:可以尽早发现由于软件集成所带来的Bug,及时进行更正。原因在于由软件集成而引入的Bug一般涉及到两个或多个程序员书写的代码,相对来说比较难于Debug。如果不及早进行集成,就不能发现该Bug;一旦集成之后,发现该Bug,就要花费大量的资源来进行Debug。但是如果使用持续集成,这种Bug在被引入的初始阶段就能够被发现,程序员可以检查相对少的源代码就可以更改该Bug,这时所付出的代价是最小的。还可以有效的避免程序员在错误的路线上越走越远,以至于在项目后期为其付出巨大的代价。举例来说:Tom和Jerry分别工作在不同的模块A和B上,其中A模块需要依赖B模块中的代码。如果B模块中的程序有错误,则会影响到A模块。如果Jerry在开发B模块的过程中引入了Bug,使得Tom开发A模块是工作在一个错误的基础上。如果两人的程序长时间不进行集成,则Tom就会在错误的开发路线上越走越远。持续集成还可以有效的降低由于软件集成所带来的风险。目前已经作为许多流行的软件开发理论的基础组成部分,例如XP,StagingDelivery,RUP中的迭代开发等等。许多软件公司都使用“NightlyBuild”,或“DailyBuild”等方式来强制程序员每天至少进行一次集成(Microsoft就是使用DailyBuild的方式进行持续集成的)。实践已经证明,持续集成对于提高软件质量,针对软件开发项目进行有效的风险管理有着不可替代的作用。持续集成的意义在于使项目随时具有一个明确的“最近状态”。项目团队中的成员的所有工作都是建立在该状态之上的:程序员基于该状态编写代码;测试人员针对该状态进行软件测试。更为重要的是项目管理人员可以根据项目的最新状态对项目的进度、风险、资源使用情况等进行有效的评估,为最终的项目成功打下坚实的基础。HudsonDOC第6页共23页6另外,现代软件开发语言(例如:C、C++,Java等)决定了持续集成的重要性。在这些语言中,往往是由多个源程序文件来完成某一特定的功能;每一个源代码文件也往往不是只服务于某一个单一系统功能。而这些程序文件往往不是由同一个程序员编写,如果这些源代码文件不是经常的进行集成,则必然在最终的集成过程中为开发团队带来巨大的麻烦,很有可能造成BuildBreak。3持续集成工具一览ThomasCarlyle(托马斯·卡莱尔是苏格兰评论、讽刺作家、历史学家。他的作品在维多利亚时代甚具影响力。)说:“人类是使用工具的动物。没有工具,人什么都不是;有了工具,人无所不能。”金融家们创造了复杂的金融工具,并利用这些工具制造了财富神话,制造了著名的跨国公司,也制造了世界范围的危机。软件精英们为了让自己的工作效率更高,有更多时间去做想做的事,也创造了各式各样的工具。持续集成已经不是一个新概念,在这个概念发展的十多年间,出现了支持这一概念的众多工具。这些工具的组合使用,为软件开发提供了强大的支持。3.1持续集成工具的分类和功能一般来说,持续集成工具可以分成两大类:自动化构建工具和构建计划安排工具。自动化构建工具自动化构建工具有这样一些基本功能:代码编译、组件打包、程序执行和文件操作。编译源代码是构建的主要工作之一,为了提高效率,编译应该根据相应的源代码是否发生改变而有条件地执行。组件打包是将编译的结果和其他需要包含的文件组织在一起,形成可以部署的组件。构建工具应该知道何时需要重新打包。程序执行是指构建工具能够在它支持的平台上,调用所有提供命令行接口的程序。构建工具应该支持创建、拷贝、删除文件和目录等操作。某些自动化构建工具还有一些扩展功能:执行开发者测试、版本控制工具集成、文档集成、部署功能、代码品质分析、支持扩展、多平台构建、加速构建。虽然构建工具可以通过命令行执行的方式来集成构建工具和测试工具,但如果它提供更直接的集成方式,开发者就更省力。同样,如果构建工具能够直接与版本控制工具集成,开发者也会觉得更方便。文档集成是指构建工具能够自动从源代码中抽取并生成API文档。构建工具还可以将打包好的组件自动部署到目标测试环境中去。构建工具一般通过一些第三方插件,支持对代码品质进行分析。而提供插件接口,是构建工具实现可扩展性的通用方式。如果您开发的软件需要在多个平台上构建并测试,