持续集成的做用、过程和优点javascript
简单说,持续集成就是快速且高频率地自动构建项目的全部源码,并为项目成员提供丰富的反馈信息。css
快速:集成的速度要尽量地快,开发人员不但愿本身的代码提交半天以后才获得反馈。html
高频率:频率越高越好,例如每隔一个小时就是不错的选择,这样问题才能尽早地被反映出来。java
自动:持续集成应该是自动触发执行的,不该该手动参与。web
构建:包含编译、测试、审查、打包、部署等工做数据库
全部源码:全部团队成员提交到代码库里的最新的云代码。apache
反馈:持续集成应该经过各类快捷的方式告诉团队成员最新的集成装填,当集成失败的时候,反馈报告应该尽量第反映失败的具体细节。tomcat
一个典型的持续集成场景是这样的:开发人员对代码作了一些修改,在本地运行构建并确认无误以后,就更改提交到代码库。具备高配置硬件的持续集成服务器每隔30min查询代码库一次,发现更新以后,签出全部最新的源代码,而后调用自动化构建工具构建项目,该过程包括编译、测试、审查、打包和部署等。而后步行的是,另一名开发人员在这一事件段也提交了代码更改,两处更改致使了某些测试的失败,持续集成服务器基于这些失败的测试建立一个报告,并自动发送给相关开发人员。开发人员收到报告以后,当即着手调查缘由,并尽快修复。服务器
一次完整的集成每每会包括如下6个步骤:app
1)、持续编译:全部正式的源代码都应该提交到源码控制系统中,持续集成服务器按必定频率检查源代码控制系统,若是有新的代码,就触发一次集成,
旧的已编译的字节码应当所有清除。
2)、持续数据库集成:在不少项目中,源代码不只仅指JAVA代码,还包括数据库SQL搅拌,若是单独管理他们,很容易形成项目其余代码的不一致,形成混乱。
持续集成也应该包括数据库集成,每次发现新的SQL脚本,就应该清理集成环境数据库,从新建立表结构,并填入预备的数据,这样就能随时发现脚本的错误,
此外基于这些脚本的测试还能进一步发现其余相关的问题。
3)、持续测试:有了JUnit之类的框架,自动化测试就成了可能,编写优良的单元测试并不容易,好的单元测试必须是自动化的、可重复执行的、不依赖于环境的、
而且可以自我检查的。除了单元测试,有些项目还会包含一些依赖外部环境的集成测试,全部这些测试都应该在每次集成的时候运行,而且在发现问题的时候产生具体报告。
4)、持续审查:注入Checkstyle和PMD之类的工具可以帮助咱们发现代码中的坏的味道,持续集成能够会用这些工具来生成各种报告,如测试覆盖率报告、Checkstyle报告、
PMD报告等。这些报告的生成频率能够下降一些,如每日生成一次,当审查发现问题的时候,能够给开发人员反馈警告信息。
5)、持续部署:有些错误只有在部署以后才能发现,他们每每具体容器或者环境相关的,自动化部署可以帮助咱们尽快发现这类问题。
· 6)、持续反馈、持续集成的最后一步的反馈,一般是一封电子邮件,在重要的时候将正确的信息发给正确的人。若是开发者一直收到与本身无关的持续集成报告,
他慢慢就会忽略这些报告,基本的规则是:讲集成失败报告发送给此次集成相关的代码提交者,项目经历应该收到全部失败报告。
持续集成须要引入额外的硬件设置,特别是对持续集成服务器来讲,性能越高,集成的速度就越快,反馈的速度就越快。持续集成还要求开发者使用各类工具,
如源码控制工具、自动化构建工具、自动化测试工具、持续集成软件等。这一切无疑都增长了开发人员的负担,而后学习并适应这些工具及流程是彻底值得的,由于持续集成的好处不少:
尽早暴露问题、减小重复操做、简化项目发布、简历团队信心。
构建Web应用
基于java的Web应用,其标准打包方式是WAR。WAR与JAR相似,只不过它能够包含更多内容,如JSP文件、servlet、java类、web.xml配置文件、依赖jar包、静态web资源等。
一个典型的WAR文件会有以下目录结构:
一个WAR包下至少包含两个子目录:META-INF和WEB-INF。前者包含了一些打包数据信息,后者是WAR包的核心,WEB-INF必须包含一个Web资源表述文件web.xml,它的子目录
classes包含全部项目的类,而子目录lib包含全部项目依赖JAR包,classea和lib目录都会在运行时候被加入到Classpath中。除了MET-INF和WEB-INF外,通常的WAR都会包含不少Web
资源如,html或者js文件。
用户必须为Web项目显示指定打包方式为war。Maven对Web项目的布局结构也有通用的约定。
在src/main/webapp/目录下,必须包含一个子目录WEB-INF,该子目录还必须包含web.xml文件。其余文件和目录包括html、jsp、css、javascript等。
使用jetty-maven-plugin,测试Web页面的作法一般是将项目打包并部署到Web容器。Web页面测试应该仅限于页面的层次,例如JSP、CSS、JavaScript的修改,其余代码修改,
请编写单元测试。
jetty-maven-plugin可以帮助咱们节省时间,它可以周期性地检查项目内容,发现项目变动后自动更新到内置的Jetty Web容器中。它帮咱们省去了打包和部署的步骤。它默认
就很好地支持了Maven的项目目录结构。
在该插件配置中,scanIntervalSeconds表示该插件扫描项目变动的时间间隔。若是不进行配置,默认值是0,表示扫描,用户就失去了所谓的自动化热部署的功能。webappConfig
元素下的classPath表示项目部署后的context path。
默认状况下,只用org.apache.maven.plugins和org.codehaus.mojo两个groupId下的插件才支持简化的命令行调用,便可以运行 mvn help: system,但maven jetty: run就不行
由于他的groupId是org.mortbay.jetty。为了能在命令行运行mvn jetty: run,用户须要配置settings.xml 以下:
启动命令:mvn jetty:run 默认监听端口是8080.并将当前项目部署到容器中,同时还会根据用户配置扫描代码改动。
mvn jetty:run -Djetty.port=9999 修改端口参数
以上仅仅展现jetty-maven-plugin最核心的配置,若是有须要,还能够自定义web.xml的位置、项目class文件的位置、web资源目录的位置等。standalong模式的配置样例
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat6x</containerId><!--表示容器类型-->
<home>D:\cmd\apache-tomcat-6.0.29</home><!--表示容器的安装目录-->
</container>
<configuration>
<type>standalong</type> <!--表示部署模式-->
<home>${project.build.directory}/tomcat6x</home><!--表示复制容器的配置到什么位置,这里表示构建输出目录,即target/下的tomcat6x子目录-->
</configuration>
</configuration>
</plugin>
cargo-maven2-plugin的groupId是org.codehaus.cargo,这不属于官方两个maven插件groupId,所以须要用户将其添加到settings.xml的pluginGroup元素中以方便命令行调用。
配置好以后,让Cargo启动Tomcat并部署应用,只须要运行:$ mvn cargo:start
使用Cargo实现自动化部署
部署至本地容器,Cargo是一组帮助用户操做web容器的工具,它可以帮助用户实现自动化部署,并且几乎支持全部的web容器,如tomcat、jBoss等。Cargo经过cargo-maven2-plugin提供了maven集成
Maven用户可使用该插件将Web项目部署到Web容器中。虽然cargo-maven2-plugin和jetty-maven-plugin的功能看起来很类似,可是他们目的是不一样的,jetty-maven-plugin主要用来
帮助平常的快速开发和测试,而cargo-maven2-plugin主要服务于自动化部署。
Cargo支持两种本地部署方式,分别为standalone模式和existing模式。在standlong模式中,Cargo会从Web容器的安装目录复制一份配置到用户指定的目录,而后再此基础上部署应用,
每次从新构建的时候这个目录都会被清空,全部配置被从新生成。而在existing模式中,用户须要指定现有的Web容器配置目录,而后Cargo会直接使用这些配置并将应用部署到其对应的位置。
部署至远程容器,可让cargo部署应用至远程的正在运行的Web容器中。
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>1.0</version>
<configuration>
<container>
<containerId>tomcat6x</containerId>
<type>romote</type> <!--必须为romote,若是不显示指定,Cargo使用默认值installed,并寻找对应的容器安装目录或者安装包-->
</container>
<configuration>
<type>runtime</type><!--表示既不使用独立容器配置,也不实用本地现有的配置,而是依赖于一个已运行的容器-->
<properties>
<cargo.remote.username>test</cargo.remote.username>
<cargo.remote.password>test</cargo.remote.password>
<cargo.remote.manager.url>http://localhost:8080</cargo.remote.manager.url>
</properties>
</configuration>
</configuration>
</plugin>
配置完成以后运行命令,$mvn cargo:deploy 若是容器已经部署了当前应用,Cargo就先将其卸载,而后再从新部署。