前言
但凡一個略有規模的專案都需要一個持續整合環境的支撐,為什麼需要持續整合環境,我們來看一個例子。假如一個專案,由A、B兩位程式設計師來協作開發,A負責前端模組,B負責後端模組,前端依賴後端。A和B都習慣使用SVN作為程式碼管理工具,他們分別開始工作,一個功能完成後會提交到SVN,以便對方能夠使用。一天B告訴A,我的某個功能完成了,提交到SVN,你更新下來試一下。A便從SVN更新下來程式碼,結果一試,我檫報錯,於是告訴B你的程式碼有問題,B檢查了一下確實有問題,然後B經過1個小時修改後,重新上傳到SVN,A更新下來可以使用了。又過了幾個小時,A發現B的程式碼仍然有問題,B檢查了半天,沒找到問題所在,後來開發組長檢查他們的程式碼發現是兩個人使用不同版本的jar包導致的,這個問題確認難以發現,A把jar包的版本弄得和B一樣,A和B又開始繼續工作。終於有一天專案完成了,需要釋出程式,這時A從自己的開發環境上編譯一個版本,把他上傳到伺服器上,程式執行的前幾天比較穩定,後來A有點急事請假了,但伺服器上的程式這時好像出現了問題,這時B只能使用自己的電腦除錯、解決問題並試著發一個版本,但因為他平時做後端,對版本釋出不是很熟悉,又搞了半天終於弄好了。專案上線了,穩定執行了半年,後來A、B先後離職了,新來的C負責維護這個專案,儘管A、B在離職前做了一些工作交接,但當C真正接手的時候才發現頭大,我檫居然註釋都沒寫,有沒有這麼坑的,由於C開始硬著頭皮看程式碼,發現程式碼中各種飄逸寫法,各種為了臨時需求而打的補丁,C幾乎抓狂。
以上的例子有點誇大,但或多或少都可能遇到過,我們需要一種規範來約束這個開發過程,使開發過程嚴格有序的進行。
從問題出發
就以上面這個例子,我們看其中暴露出了哪些問題:
1、團隊彼此協作不流暢,出現彼此阻塞的情況;
2、使用的類庫版本不統一,造成難以估計的風險;
3、程式碼未經嚴格測試就上傳,造成不斷的返工;
4、版本釋出規範欠缺,版本質量不能保證;
5、程式碼質量低,其他人難以接手。
團隊開發時,我們常常約定好彼此之間的介面規範,然後開始各自開發,開發完成後,按照介面規範對接起來,這是一個理想的流程,但現實往往不那麼順利,問題常常在於,介面規範可能根據需求變化而經常變更,而且在實際對接時經常發現諸多問題。我們無法透過工具來解決這些問題,只能要求開發人員在制定介面規範時,為可能變更的需求多一些擴充套件,在開發時多考慮諸多素質,儘量將減少對接過程中的問題。下面將講述如何使用Maven和Nexus保證開發人員引用統一的類庫版本,以及如何將自己開發的模組上傳至Nexus伺服器,以提供給其他模組引用。
關於Maven和Nexus的搭建在Maven實戰(Maven+Nexus建立私服【Linux系統】)中已經介紹過,在此介紹下主要步驟:
1、下載maven(讀:妹吻)和nexus(讀:耐克色兒絲):
http://maven.apache.org/download.cgi
http://nexus.sonatype.org/downloads/
2、將下載的nexus放置到linux伺服器解壓並啟動:
選擇自己的系統並進入:
啟動nexus
./nexus start
nexus啟動成功,訪問:http://192.168.6.204:8081/nexus/
3、將下載的maven解壓放置在開發機上(windows),並配置conf目錄下的setting.xml檔案:
(1)在<settings><profiles></profiles></settings>節點之間新增配置:
接著在<settings></settings>節點之間新增配置:
以上配置好了連線Nexus私服。
(2)安裝eclipse的m2eclipse外掛,並配置maven。
m2eclipse的安裝地址:http://m2eclipse.sonatype.org/sites/m2e(安裝過程略)
安裝完成後配置maven:
配置eclipse的maven為本地下載的maven地址。主要為了方便配置和版本管理。
至此,nexus和maven就搭建配置完成了,下面我們要利用這個環境解決兩個問題:
1、不同的模組專案都使用統一的類庫版本;如spring都使用3.1.2.RELEASE,log4j都使用1.2.17。這樣避免因為jar包版本的不同,引發的諸多問題。
2、模組開發完畢後,將編譯的庫檔案釋出到nexus私服上,以便其他模組引用。
這裡說一下maven的一個特性,繼承。簡單來說繼承就是先建立一個父專案,其他專案如果繼承這個父專案,就可以繼承這個專案定義的庫檔案及版本。利用這個特性,我們可以讓多個模組都繼承一個父專案,而在父專案中定義好類庫的版本,這樣所有模組都使用統一的類庫檔案。例如:
建立名為maven-parent的父專案,pom配置為:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.cnblogs.leefreeman</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<!-- junit -->
<junit.version>4.10</junit.version>
<!-- servlet -->
<servlet-api.version>2.5 </servlet-api.version>
<!-- log4j -->
<log4j.version>1.2.17 </log4j.version>
<!-- commons.codec -->
<commons.codec.version>1.7</commons.codec.version>
<!-- maven-support -->
<maven-support.version>0.0.1-SNAPSHOT</maven-support.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- commons包 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>${commons.codec.version}</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
這個pom定義了一些類庫以及它的版本。
然後再建立模組專案:maven-sample(web專案)、maven-support(支撐模組,包括一些工具類以及業務封裝,提供給maven-sample引用)。
maven-sample的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cnblogs.leefreeman</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-sample</artifactId>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
</dependencies>
<build>
<finalName>maven-sample</finalName>
</build>
</project>
maven-support的pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.cnblogs.leefreeman</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>maven-support</artifactId>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
</project>
透過以上配置,maven-sample和maven-support引用的jar包,都會使用相同的版本:
接下來我們解決協作開發的問題,maven-support開發完畢之後,將之釋出到nexus伺服器,以便maven-sample可以引用。我們需要3步:
1、本地maven的conf目錄下的setting.xml,在<servers></servers>節點之間新增:
2、在maven-support專案的pom.xml中,<project></project>節點之間新增:
<!-- 構件部署倉庫 -->
<distributionManagement>
<repository>
<id>releases</id>
<name>釋出版本倉庫</name>
<url>http://192.168.0.109:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>快照版本倉庫</name>
<url>http://192.168.0.109:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
3、對maven-support專案進行編譯,並執行釋出命令:
可以看到maven-support已經成功釋出到nexus私服中:
這樣maven-sample就可以引用maven-support模組,而開發maven-support的人則可以繼續開發,持續釋出新版本。
小結
本文主要介紹maven和nexus的環境搭建,以及怎麼使用maven和nexus統一管理庫檔案和版本,怎麼講自己的模組上傳至nexus私服,供其他模組引用。這樣我們基本解決了兩個問題:
1、團隊彼此協作不流暢,出現彼此阻塞的情況;
2、使用的類庫版本不統一,造成難以估計的風險;
下一篇將使用jenkins、svn、tomcat以及sonar解決自動化測試、自動化版本釋出、程式碼質量檢查等問題。