持续集成
在介绍jenkins之前需要先了解一个概念CI(Continuous Integration)持续集成,不了解的可以先看下这篇文章:持续集成,这个概念来自很流行的敏捷开发,讲究快速的发现问题,快速发现问题需要的是快速的迭代开发,不同于传统的瀑布式开发。持续集成解决了软件开发过程中的很多痛点。最好的代码提交方式是:在本地经过一系列测试后,再提交到版本控制系统。而且提交要尽可能的小批量频繁提交,因为这有助于迅速发现和解决问题。
jenkins简介
了解了CI的概念,那么jenkins是什么,其实就是我们实现CI的一种工具,jenkins是开源的,当然业界还有其他的CI工具,但是jenkins使用的是最广泛的,它的前身是Hudson。jenkins的实现架构和eclipse非常相似(基于插件),想想eclipse的强大功能,jenkins同样可以通过扩展的插件来实现丰富的功能。jenkins提供了非常简洁的页面来管理这些插件和构建任务。jenkins默认对于CVS和SVN提供了方便的支持,对于项目管理工具则能够很好的支持Maven,如果你的项目是基于maven来管理的,那么使用jenkins会感觉到异常的简单。
同时jenkins非常善于站在一段时间的角度上,分析构建的稳定性,不同的稳定性使用不同的天气标示。比如阴天,晴天,等,都表示不同的含义。
jenkins的安装
Jenkins很容易安装,可以跑在任何地方。你可以把它作为单独的应用程序或者运行在Java应用服务器比如Tomacat中。因为Jenkins是一个java应用程序,你需要在机器上安装jdk。Jenkins有一种war包形式的安装包,可以下载最新的版本。
jenkins中的job
一个完整的构建可能需要很多步骤,每个步骤都称作是一个job。一个build job是一个专一做某事的步骤,比如编译,测试,打包,部署等等。构建任务是各种各样的。可能你需要去编译源码,对程序做单元测试,生成代码的质量报告,生成api文档,部署应用,做自动化测试等等。
jenkins中提供了自由式的风格,maven风格等几种job模式。
最简单的jenkins应用
目前绝大多数的开发团队都会使用版本控制系统来管理源代码,因此一种最简单的使用jenkins的场景诞生了。我们知道软件开发中最基本的一个步骤就是编译源码,现在的很多IDE都支持该功能。但是如何去编译版本控制系统的代码,最简单和常用的方式是自己写一个编译脚本,比如ant脚本。如果你们的项目使用的maven,那当然更简单,其他的诸如git等就不在讨论了。jenkins最基本的一个功能就是:当有人提交代码到版本控制系统的时候,就拿SVN来说吧,jenkins能够自动检测到代码的变化,并将源代码下载到jenkins服务器本地,然后调用构建脚本去编译源码。这是最基本的一个场景。后面复杂的jenkins流水线都是基于此。
除了提交构建,也能够定义隔某段时间便构建一次,或者定时轮询SCM的改变去触发构建。当然也支持手动的构建,这些都统称为构建触发器。构建步骤中可以执行我们自定义的shell或者batch等等脚本,非常的灵活。
Jenkins的家目录
上面提到jenkins服务器本地,其实jenkins为每个项目都会建立一个自己的workspace,源码会下载到这个目录下,然后编译的动作在该目录中进行。这里不得不提到jenkins中一个非常重要的概念——JENKINS_HOME jenkins的家目录,可以为该环境变量指定一个值否则会使用默认值。该目录的结构大概为:
jobs下面按照项目的维度进行划分,每个项目下有builds和workspace目录,其中我们所讲的源码会保存在各个项目的workspace中,builds目录包含构建的历史记录。
自动化测试
如果jenkins仅仅能够做编译源码的动作,那你太小看他了,源码编译出来的可执行文件比如war包jar包等等,jenkins统统能够帮你管理起来。jenkins同样有很多插件方便完成自动化的测试,这些测试包括单元测试,功能测试,集成测试,性能测试,验收测试等等,其中开发的过程可以使用TDD等方式来进行。进行自动化的测试仅仅是一部分功能,其中比较重要的是需要收集测试的结果,如果能够以图形化的方式展示出来那就更好了。没错,jenkins能够做这些事情,只需要告诉jenkins测试的结果在哪里,它会去取,并且生成可视化的图形。
另外一种关于自动化测试的是代码的覆盖率,jenkins同样支持对代码覆盖率的统计。
通知
一旦编译失败或者测试失败或者代码质量不合格等等,需要立马让相关的人知道情况,通常的方式是发送email,只需要在jenkins上简单的配置SMTP服务器等一些步骤即可,当然通知不仅仅这么简单,还有些复杂的功能,比如更具不同的人发送不同的邮件内容。或者直接使用即时通讯软件发送即时消息。或者发送短信。这些jenkins都能实现。
代码质量
在各种自动化测试都完毕的时候,一般需要进行代码的质量度量,比如圈复杂度,checkstyle,findbugs等等静态检查。这些检查都可以使用jenkins的插件完成,同样会收集质量结果,做展示,很方便开发人员进行代码重构。
自动化部署
自动化部署目的就是减少不必要的时间。最简单的是自己实现部署的脚本然后供jenkins去调用,但是对于复杂的部署需求,自己实现脚本恐怕有些力不从心,我们可以借助插件完成——Puppet或者Chef。
关于数据库的自动化升级可以使用脚本实现或者使用工具Liquibase。
自动化升级中需要关注的是回滚的问题,解决回滚的最简单的思路是升级前的备份。包括应用和数据库的数据。
高级构建
参数构建类似普通的构建任务,但是功能更强大。可以为本次构建指定一些参数,这些参数可能会在某几个构建中被使用到,参数的传递由jenkins去维护。由此一个普通的构建通过获取不同的参数能够表现的更多样化。
更强大的是多配置构建,类似参数构建,提供一个配置列表,比如针对不同的数据库或者浏览器的列表,jenkins会自动的执行不同场景下的测试,这些测试可以并行的执行,从而大大的减少了测试的时间。
分布式构建
jenkins也支持master/slave的分布式方式,master主要用来分发构建任务给slave,实际的执行在slave中。Master监控slave的状态,并收集展示构建的结果。但是在实际情况中master同样可以执行构建任务。可以通过master指定某个项目总是运行在特定的slave或者某类slave或者简单的任何一台slave中。
分布式构建中,jenkins提供了对代理节点的监控,如果发现某台slave不可用,则会主动将其下线,避免后续的任务被分配到该节点上。
流水线
所谓的流水线很容易理解,就是整个构建流程按照一定的流程去构建。当你的构建步骤变得复杂的时候,并且并行和串行都有的时候,通常就不太容易管理了。流水线能够方便的定义某个构建后要触发的下一个构建,或者同时触发的后面几个构建。当然也能够等待某几个构建执行完毕后去执行某一个构建。其中TheDependency Graph View插件能够帮助你分析构建任务之间的关系。并且如果涉及到构建的资源竞争,也提供了锁的功能。
jenkins中的安全管理
jenkins中有个维度来管理安全,一个是安全域一个是授权。安全域能够识别出合法的用户,授权针对合法的用户给出不同的权限。最简单的授权是允许所有的合法用户做任何事情。
最简单的管理用户账号的方式是使用jenkins内建的数据库,但是也能够和其他的用户管理系统做集成。针对授权有好多种不同的策略,比如基于项目,基于角色。
另外一种重要的功能是审计,也就是记录用户的操作日志。有两种插件能够实现该功能。Audit Trail插件能够记录用户的操作动作。JobConfigHistory插件能够存储前一个版本系统的变化和job的配置文件。
总结:
持续集成一般会经历一下几个阶段
阶段一—没有构建服务器
最初的阶段,团队没有任何一种构建服务器。软件由开发人员手动的去构建,尽管使用的是Ant脚本或者类似的东西。源码可能存储在一个中央源码仓库中,但是开发者未必要定期的提交更改后的代码。有时候在一个版本要发布的时候,开发人员手动的去集成这些变化,这是一个非常痛苦的过程。
阶段二—夜间的构建
在这个阶段,团队有一台构建服务器,并且定时的去执行构建任务(通常在夜里)。因为并没有一个可靠的可重复的单元测试,所以这里的构建通常只是代码编译。如果有自动化测试,也并没有强制集成到构建阶段,也许根本不会正确的运行。但是现在开发人员已经能够有规律的定期提交代码了,至少在每天下班前。如果一个开发人员提交的代码和另外一个人有冲突,构建服务器会在第二天的早上将告警通过邮件发出来。然而,整个团队只是将构建服务器作为一个参考—如果构建挂了,他们并没有意识去立即把它修复好,因此构建可能会在一段时间内不可用。
阶段三—夜间构建和基本的自动化测试
团队现在已经更加严格的使用持续集成和自动化测试了。构建服务器被配置为当有代码提交的时候便会执行构建,团队的成员也可以很方便的看到是哪些代码中的变化引起了构建,这些变化引发了什么问题。除此之外,构建脚本编译应用并且自动的执行一些单元和集成测试。对于邮件,构建服务器能够更加积极主动的去呈现构建中出现的问题。失败的构建也能够被快速的修复。
阶段四—进入度量
自动化的代码质量和覆盖率度量也能够执行了,并且可以帮助评估代码的质量和测试的相关性和有效性。代码质量的构建也能够为应用生成API文档。所有的这些帮助团队去维护高质量的代码。团队中可以设置一个醒目的屏幕去时刻展现项目的状态。
阶段五—更严格的测试
持续集成的好处是非常接近立体的测试。现在,测试驱动开发(TDD)被广泛的应用,对于自动构建的结果更加的有信心。对于应用程序不再是简单的编译和测试,而是会继续更复杂的端到端测试和性能测试。
阶段六—自动化验收测试和自动化部署
验收测试驱动开发(Acceptance-Test Driven Development)在这个阶段被应用,引导开发的工作并且提针对项目的状态提供一个高层次的报告。这些自动化测试使用行为驱动测试(Behavior-Driven Development)和验收测试驱动开发工具,并且从商业的角度生成开发人员不理解的报告。因为这些高层次的测试在项目的早期开展,因此能够清晰的指出,哪些特性已经完成了,哪些需要后面去完成。每当代码有改变或者夜里,应用程序被自动的部署到QA的测试环境来完成测试。当测试人员完成了充分的测试后,应用程序可以被一键式的部署到生产环境。当然也能够通过构建工具去备份当前的发布版本,或者当有问题出现的时候,回归当前的版本。
阶段七—持续部署
处于对自动化的单元、集成、验收测试的信任,现在团队能够应用自动化部署技术,直接将新的特性增加到前一个版本中,该版本处在生产环境中。
这些阶段可以是按部就班的来,但有时候也不一定非得按照上面的步骤,比如在集成代码质量和覆盖率测试之前可以先完成自动化的web测试。这里只是给出了部署一套CI的常规流程。