持續集成之“軟件自我識別”

作者: 喬梁  來源: InfoQ  發布時間: 2012-01-07 15:33  閱讀: 1862 次  推薦: 2   原文鏈接   [收藏]  

  在前文《自動化部署》中,我們討論了自動化部署。通過對部署操作腳本化、部署驗證自動化、部署環境版本控制、生產部署全自動化等諸多實踐,可以讓部署完全處于受控狀態。然而,作為運維人員,是否曾經有人走過來問你這樣的問題:“當前生產環境上部署的是哪個軟件版本?”你是否遇到過這樣的情形,即使手里拿著一個jar文件或dll文件,也無法知道它到底是哪個版本。也許你可能認為,這算不了什么,到某個管理平臺上查一查部署記錄就行了。可是,如果發現在生產環境的集群服務器上,不同機器上部署的同一個程序文件(比如.war文件)的大小卻不相同,哪一個的大小是正確的呢?作為運維人員,你當時的心情會是什么樣呢?

  地點:運維人員辦公室

  下午五點鐘,運維人員Steven習慣性地打開線上運維監控平臺,一頁一頁地快速查看著監控數據。這已經成了他的一個工作習慣,只要有新版本上線,他總是經常打開監控頁面看看。“好像沒什么問題。”他暗自慶幸,“可以正點下班了”。

  忽然,他的目光停在了一個流量曲線上。“為什么波動會這么大呢?”他又查看了其它幾個相關曲線,沒有什么問題,但直覺告訴它,可能新版本部署有問題。于是,他開始了更詳細的跟蹤分析。

  時間隨著電子表的跳動,一分鐘一分鐘的過去了。終于,Steven站了起來,深深地吸了一口氣。此時,時鐘已指向晚上八點啦。他發現,在生產環境的集群中,有五臺機器的應用程序文件包與其它機器上的文件包相比,文件大小不一樣。到底哪個是正確的呢?

  Steven首先查了一下部署管理日志系統,文件名為abc,正確版本是1.21。可是這兩種文件的文件名都是abc.war。從文件名上沒有什么區別。無奈,Steven操起電話,把開發人員Bob從家中叫了回來,一起解決這個問題。

  又經過三個多小時的忙活,兩個人終于找到了正確的版本。原來,只有那五臺機器上的二進制包是正確的,其它機器上的都不對。這兩個版本都屬于1.21,只不過,其中一個是快上線前修復bug的一個測試版本,而另一個是正式上線版本。它們在版本庫中的revision只差一個。可能是誰部署時不小心搞錯了。

  地點:開發團隊工作室

  第二天一大早,Steven在站會上把這個Case通報了一下,引起了Joe的注意。Joe說道:“我們站會之后討論一下,怎么避免這類問題的發生吧。”

  于是,站會后,Joe、Bob、Alice和Steven在一個角落里坐了下來,并叫來了運維主管Tom。

  “我們都使用了自動化部署,怎么還會出現這個問題呢?”Tom不解的問道。

  Steven答道:“我查看了一下腳本,這部分沒有做驗證,我今天把它加上。不過,這兩個版本的文件名稱是一樣的,只能在部署前拿到它們的MD5,進行比對驗證。”

  Alice說道:“我們還可以對文件名進行規范,在文件名上加入版本號,比如appname-xxx_xxx。”

  “這也是解決問題的一個辦法。但是,你知道,文件是很容易被重命名的。”Joe說道。

  Tom又說道:“我們可以把MD5和一些元數據信息,比如revision等放到一個無數據描述文件中,并打包在應用程序中。比如,在Java領域,所有的.jar, .war 和.ear文件都允許將這些信息放在META-INF/MANIFEST.MF文件中。”

  “嗯,這也是種好辦法。但是,如果能讓應用程序自我識別,不是更加直接嗎?”Joe說道。

  大家一臉迷惑地看著Joe,不明白他在說什么。

  “我們讓應用程序告訴我們它是什么版本,不就是自我識別嘛!”Joe笑道,“其實,這也不是什么新鮮技術,你們一看就明白了。”

  Joe打開筆記本,接上了21寸的顯示器,把他們使用的持續集成和發布管理工具Cruise的界面打開了,如圖1所示。

圖1 軟件自我識別版本信息

  接著說道:“這是我們用的Cruise服務器的信息頁面。從這里,我們可以很清楚地看到這個應用程序的運行環境信息,比如Java虛擬機的版本、操作系統類型與版本、服務器存儲空間信息、應用程序的數據庫版本、license信息等等。更重要的是第一行的服務器版本信息。(1)表示其對外發布的版本號;(2)和(3)可能對應著其revision號。”

  “我從來沒有看過這個頁面。”Bob和Alice同時說道。

  “這里面的信息很多啊。”Steven有點兒興奮的說道,“如果我們的應用程序也可以這么做的話,我在這方面的運維工作會輕松很多,因為我可以把自動化部署腳本和自動化部署驗證做得更強大一些。”

  Alice說道:“我們的很多組件都以庫文件方式存在,沒有界面,那怎么辦?”

  “沒有關系,”Steven說道:“界面對自動化運維來說是次重點,最重要的是可以通過一些API以命令行的方式來執行。”

  Joe點頭說道:“讓我們來總結一下吧,看看接下來做什么。”

  應用程序自識別的應用場景與實現方式

  • 可以直接拿到應用程序安裝文件或二進制包時
    從它的元描述文件(metaData)中查看它來自于哪里。大多數現代二進制格式支持以某種方式做到這一點。比如,你使用Java時,所有的.jar, .war 和.ear文件都允許將這些信息放在META-INF/MANIFEST.MF文件中。如果你是在Windows上,創造性地使用versioninfo resources也能達到同樣的效果。注意:并不是說把這些信息放在文件名中,因為修改文件名的可能性很大。
  • 當你無法拿到正在提供服務的二進制文件時(比如應用程序是一個遠端服務,無法直接登錄到服務器上)
    最容易的方法是能夠訪問一個已知的URL或者服務調用API,它能夠告訴你任何你想知道的信息。到底是什么樣的UR或服務調用并不重要,只要需要知道這些信息的人知道怎么調用它就行了。

  當然,API方式還有更多的用途。

  比如,當你使用持續部署實踐時,你在部署之前可以驗證一下將要部署的二進制是不是正確的版本。

  然后,你可以在部署之后,使用這個服務調用去驗證應用程序的正確版本是不是啟動并運行了。

  如果有一個動態更新的系統信息顯示板,你就可以快速且方便地看到哪個軟件安裝的是哪個版本,而不用去更新文檔,因為文檔很容易忘記更新。

  最后,Steven和開發團隊一起,商定了一些細節。

  1. 每個組件的文件名按照如下格式生成:組件名+對外版本號+版本庫revision號。
  2. 每次構建中生成該文件的MD5碼。
  3. 在打包時,將這些元數據信息寫入元數據描述文件。由于使用subversion版本控制庫,而且,各組件的代碼庫會做遷移,所以元數據中,至少包含該構建版本對應的源代碼svn庫的URL和revision。
  4. 每個組件都提供統一的API調用whoami,要求返回形如NAME0-PUBLIC VERSION:svn URL@revision的自識別信息。
  5. Steven根據上述信息,更新部署腳本,以及自動化部署驗證測試。
2
0
 
標簽:持續集成
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()