maven快照版本和发布版本
在使用maven過程中,我們在開發(fā)階段經(jīng)常性的會有很多公共庫處于不穩(wěn)定狀態(tài),隨時需要修改并發(fā)布,可能一天就要發(fā)布一次,遇到bug時,甚至一天要發(fā)布N次。我們知道,maven的依賴管理是基于版本管理的,對于發(fā)布狀態(tài)的artifact,如果版本號相同,即使我們內(nèi)部的鏡像服務(wù)器上的組件比本地新,maven也不會主動下載的。如果我們在開發(fā)階段都是基于正式發(fā)布版本來做依賴管理,那么遇到這個問題,就需要升級組件的版本號,可這樣就明顯不符合要求和實際情況了。但是,如果是基于快照版本,那么問題就自熱而然的解決了,而maven已經(jīng)為我們準(zhǔn)備好了這一切。
?? ? ?maven中的倉庫分為兩種,snapshot快照倉庫和release發(fā)布倉庫。snapshot快照倉庫用于保存開發(fā)過程中的不穩(wěn)定版本,release正式倉庫則是用來保存穩(wěn)定的發(fā)行版本。定義一個組件/模塊為快照版本,只需要在pom文件中在該模塊的版本號后加上-SNAPSHOT即可(注意這里必須是大寫),如下:
<groupId>cc.mzone</groupId>
<artifactId>m1</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>jar</packaging>
?? ? ?maven2會根據(jù)模塊的版本號(pom文件中的version)中是否帶有-SNAPSHOT來判斷是快照版本還是正式版本。如果是快照版本,那么在mvn deploy時會自動發(fā)布到快照版本庫中,會覆蓋老的快照版本,而在使用快照版本的模塊,在不更改版本號的情況下,直接編譯打包時,maven會自動從鏡像服務(wù)器上下載最新的快照版本。如果是正式發(fā)布版本,那么在mvn deploy時會自動發(fā)布到正式版本庫中,而使用正式版本的模塊,在不更改版本號的情況下,編譯打包時如果本地已經(jīng)存在該版本的模塊則不會主動去鏡像服務(wù)器上下載。
?? ? ?所以,我們在開發(fā)階段,可以將公用庫的版本設(shè)置為快照版本,而被依賴組件則引用快照版本進(jìn)行開發(fā),在公用庫的快照版本更新后,我們也不需要修改pom文件提示版本號來下載新的版本,直接mvn執(zhí)行相關(guān)編譯、打包命令即可重新下載最新的快照庫了,從而也方便了我們進(jìn)行開發(fā)。
?
目前在JAVA的世界中,maven已經(jīng)成為事實上的構(gòu)建標(biāo)準(zhǔn),很多開源庫的管理構(gòu)建也是基于maven的,maven本身的學(xué)習(xí)曲線比較陡峭,遵循“約定優(yōu)于配置”的理念,maven存在很多約定。本次我先描述下,關(guān)于版本的定義的選擇,SNAPSHOT or RELEASE?
版本之爭
在maven的約定中,依賴的版本分為兩類——SNAPSHOT和RELEASE。SNAPSHOT依賴泛指以-SNAPSHOT為結(jié)尾的版本號,例如1.0.1-SNAPSHOT。除此之外,所有非-SNAPSHOT結(jié)尾的版本號則都被認(rèn)定為RELEASE版本,即正式版,雖然會有beta、rc之類說法,但是這些只是軟件工程角度的測試版,對于maven而言,這些都是RELEASE版本。既然Maven提供了這兩類版本號,那么他們之前的優(yōu)劣勢是什么?分別在什么場景下使用?
解讀SNAPSHOT
同一個SNAPSHOT版本的依賴可以多次發(fā)布(deploy)到倉庫中,也就是說同一個SNAPSHOT版本的依賴可以在倉庫中存在多份,每一份都是代碼在某一個特定時間的快照,這也是SNAPSHOT的含義。
如上圖,很好地表達(dá)了SNAPSHOT的細(xì)節(jié),也闡述了一個SNAPSHOT很重要觀點——SNAPSHOT不是一個特定的版本,而是一系列的版本的集合,其中HEAD總是指向最新的快照,對外界可見的一般也是最新版,這種給人的假象是新的覆蓋了老的,從而使得使用SNAPSHOT依賴的客戶端總是通過重新構(gòu)建(有時候需要-U強(qiáng)制更新)就可以拿到最新的代碼。例如:A-->B-1.3.8-SNAPSHOT(理解為A依賴了B的1.3.8-SNAPSHOT版本),那么B-1.3.8-SNAPSHOT更新之后重新deploy到倉庫之后,A只需要重新構(gòu)建就可以拿到最新的代碼,并不需要改變依賴B的版本。由此可見,這樣達(dá)到了變更傳達(dá)的透明性,這對于開發(fā)過程中的團(tuán)隊協(xié)作的幫助不言而喻。
SNAPSHOT之殤
SNAPSHOT版本的依賴因為存在變更傳達(dá)的透明性的優(yōu)勢而被賞識,甚至被“溺愛”,有很多團(tuán)隊索性直接使用SNAPSHOT到生產(chǎn)環(huán)境中,這樣對于變更直接生效,很方便。但是作為技術(shù)人員的我們其實應(yīng)該很嚴(yán)謹(jǐn)?shù)乜创兏鼈鬟_(dá)的透明性,變更就意味著風(fēng)險,透明性更是把風(fēng)險徹底隱藏了起來,生產(chǎn)環(huán)境中存在這樣的現(xiàn)象更是心驚膽戰(zhàn)。例如:A-->B.1.0.3-SNAPSHOT,B對一個A使用的功能實現(xiàn)進(jìn)行了調(diào)整,直接發(fā)布到倉庫,A重新構(gòu)建或許就會失敗,更糟糕的是構(gòu)建成功,運行時異常。這個時候A甚至完全沒有代碼變更就突然失敗了,會帶來更多的困惑。
這也是maven經(jīng)常遭人詬病的一個因素,對于同一份代碼,構(gòu)建結(jié)果卻不具備確定性,讓很多人沮喪。當(dāng)然這個不完全是因為依賴的問題,也有maven插件的問題,maven之前的版本尋找插件策略的方式也存在不確定性,maven在版本2的時候,會去尋找最新的插件版本(如果沒配置的話)來執(zhí)行構(gòu)建,經(jīng)常會找到SNAPSHOT版本的插件,所以依賴了一個不穩(wěn)定的插件來執(zhí)行構(gòu)建,不確定性就大大增加。不過maven在3版本就改變了這個策略,會尋找最新穩(wěn)定版的插件來執(zhí)行構(gòu)建,使得構(gòu)建具備了確定性,穩(wěn)定性也好多了。說明maven本身也在SNAPSHOT的問題上狠狠摔了一跤。
歸根到底,這些問題的根源就是SNAPSHOT是變化的,是不穩(wěn)定的,而應(yīng)用(軟件)依賴于變化并且不穩(wěn)定的SNAPSHOT的依賴會導(dǎo)致自身也在變化和不穩(wěn)定中,這是穩(wěn)定性的一個大忌,依賴不穩(wěn)定的服務(wù)或者依賴,上述的maven2的問題就是一個典型反例。
RELEASE簡介
RELEASE版本和SNAPSHOT是相對的,非SANPSHOT版本即RELEASE版本,RELEASE版本是一個穩(wěn)定的版本號,看清楚咯,是一個,不是一系列,可以認(rèn)為RELEASE版本是不可變化的,一旦發(fā)布,即永遠(yuǎn)不會變化。
雖然RELEASE版本是穩(wěn)定不變的,但是倉庫還是有策略讓這個原則變得可配置,有的倉庫會配置成redeploy覆蓋,這樣RELEASE版本就變成SNAPSHOT了,偽裝成RELEASE的SNAPSHOT,會讓問題更費解和棘手,我一般稱這類人為“挖坑專家”。
記住,RELEASE一旦發(fā)布,就不可改變。
如何選擇
那么什么時候使用SNAPSHOT?什么時候使用RELEASE?這個可以從他們各自的特性上來看,SNAPSHOT版本的庫是一直在變化的,或者說隨時都會變化的,這樣雖然可以獲取到最新的特性,但是也存在不穩(wěn)定因素,依賴一個不穩(wěn)定的模塊或者庫會讓模塊自身也變得不穩(wěn)定,尤其是自身對被依賴模塊的變化超出掌控的情況。即使可以掌控被依賴模塊的變化,也會帶來不穩(wěn)定的因素,因為每次變更都有引入bug的可能性。如果這么說,那么我們是不是要摒棄SANPSHOT了呢?答案肯定是否定的。
想象下,什么情況下,模塊會一直變化或者變化比較劇烈?開發(fā)新特性的時候,所以對于團(tuán)隊之間協(xié)同開發(fā)的時候,模塊之間出現(xiàn)依賴,變化會非常劇烈,如模塊A依賴模塊B,模塊A必然需要最方便地獲取模塊B的特性,在開發(fā)期間,方便性比穩(wěn)定性更重要。可以反證下,假設(shè)模塊B使用RELEASE版本1.0.0,模塊A依賴1.0.0,現(xiàn)在模塊A出現(xiàn)了bug,需要修復(fù)下,那么A就要提供一個版本號1.0.1,這樣所有依賴A模塊都需要更新版本號,因為開發(fā)期間這種事情是如此多,所以會帶來巨變。反觀SNAPSHOT方案,如果模塊B的版本是1.0.0-SNAPSHOT,模塊A完全不需要修改版本號即可獲取模塊B的新特性。當(dāng)開發(fā)進(jìn)入預(yù)發(fā)布階段,為了生產(chǎn)環(huán)境的穩(wěn)定性,依賴應(yīng)該是RELEASE版本,因為此時SNAPSHOT版本的模塊自動獲取新特性的特點恰恰會造成生產(chǎn)環(huán)境的不穩(wěn)定性,生產(chǎn)環(huán)境上,穩(wěn)定性重于一切。
魔幻之手
現(xiàn)在已經(jīng)很明確了,在開發(fā)期間,活躍模塊的版本號使用SNAPSHOT,在生產(chǎn)期間,依賴RELEASE版本模塊。貌似,我們找到了銀彈,不過這個只是理想狀態(tài),即所有的模塊的版本都在自己的掌控或者間接掌控下,只有這樣你才能影響對應(yīng)模塊的版本號。往往是理想很豐滿,現(xiàn)實卻很骨感,如果你依賴的一個模塊只有SNAPSHOT版本,并且該模塊也很活躍,最無助的是模塊的維護(hù)人不理會你的請求,那么是否就沒轍了,只能把應(yīng)用構(gòu)建在不穩(wěn)定模塊上呢?介紹一款maven插件——versions,這是一個非常強(qiáng)大的版本管理插件,其中有個對依賴版本加鎖的特性——lock-snapshots,并且提供了參數(shù)可以控制鎖定的依賴,就可以實現(xiàn)對特定的SNAPSHOT模塊鎖定版本,執(zhí)行的命令如下:mvn versions:lock-snapshots -DincludesList="groupId:artifactId:type:classifier:version",執(zhí)行這個命令之后,對應(yīng)的版本號會變化,比如1.0.0-SNAPSHOT會變成1.0.0.20090327.172306-4,即完成了鎖定,此時這個SNAPSHOT就變成了固定小版本的穩(wěn)定版本,不會在變化了,也相當(dāng)于正式版的功能了。當(dāng)然以后也可以解鎖,詳細(xì)請看對應(yīng)文檔。
總結(jié)
以上是生活随笔為你收集整理的maven快照版本和发布版本的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Nomad入门
- 下一篇: gorm增删改查总结