持續整合之「Everything is code」

2022-02-12 04:34:09 字數 3266 閱讀 3462

在前文《軟體自我識別》中, 我們討論了如果使軟體做到自我識別,以促進自動化部署和版本檢測等工作。 隨著網際網路的飛速發展,以及基礎設施的改進,越來越多的業務被放在了「雲」端。管理數千台伺服器和各種應用程式的不同版本已經是一種常規事務了。那麼如果 管理好這些機器和**嗎?本文將介紹一些最佳實踐,來幫助大家更好的完成相關的事務。

業務壓力讓團隊人力顯得有點兒緊張。一天下午,大家在緊張的工作著,新的版本即將發布了。突然,有兩個同事的對話引起了joe的注意。

「hi,sam。過來看一下,我這裡有個自動化測試失敗了。」剛剛加入團隊的測試人員jared 叫了sam一聲。

「咦?我本地沒有這個測試,可我更新過我本地的**了呀?」sam一臉茫然地應到。

「哦,是嗎?不會吧。我也是剛剛從svn上更新了**。」jared說道。

「jared,你再更新一下,也許是你在我提交之前更新的呢。。。哦,還是一樣的結果。那到我的工作站上看一下吧。」

「噢,原來你把測試放在了這裡。」sam恍然大悟的樣子,「我們兩個人使用的測試套件版本是不一樣的。根據使用者的反饋,我們重新修改了產品的乙個小功能,所以,這部分功能的原有自動化驗收測試邏輯就不對了。」。svn**倉庫的目錄結構如圖1所示。

圖1 產品**與測試**分離

這時,joe也湊了過來。「嗯。我們應該修改一下我們的**在svn中的組織結構。把測試**和產品**放在同乙個**庫中,做到產品**與測試**同源。」

jared 問道:「為什麼要這麼做呢?我在上一家公司的時候,測試團隊也是把功能測試用例放在公司自行開發的乙個測試用例管理平台上進行管理。當需要做老版本的回歸 測試(比如v1.0)時,我們只要在這個平台上勾選上該版本對應的測試用例,再點選『執行』按鈕,就可以了。當有新版本, 比如v1.1時,只要把 v1.0的所有測試用例複製乙份,標記為v1.1,並在其上修改就可以了。測試**的組織方式常常是使用目錄結構來分離版本。」如圖2所示。

圖2 以目錄方式對測試用例進行管理

joe 回答到:「你剛才所說的做法,我也在其它公司見過。這種做法常見於使用傳統瀑布開發模式的團隊,即開發階段與測試階段分離。在開發階段,大家並不會頻繁運 行相應的自動化測試,這些自動化測試是為測試人員服務。而在我們這裡,自動化測試是為所有人服務的,開發人員隨時都會執行測試。其實,我們大部分的測試都 已經與產品**放在了同乙個**倉庫中了。只是這一部分是比較老的**,需求也一直沒有變化,自動化測試也一直執行成功,所以就沒什麼動力去遷移這部分測 試**。」

joe停頓了一下,喝了一口咖啡,接著說道:「當我們做到產品**和測試**同源時,我們只需要從乙個svn**倉庫中簽出某個版本的原始檔,就同 時得到到產品**,以及與該版本相對應的測試**。所以,不會出現版本不一致,或者需要手工挑選測試用例的問題。現在伺服器很多,應用程式使用灰度放量發布的方式,在生產環境中可能會有多個版本。假如正在執行的某個版本出現了問題,需要修復,那麼,我們很容易就能拿到與其對應的所有**。因此,不能把測試**作為**中的二等公民,而是應該得到與產品**同樣的重視。我們**庫中的目錄結構是這樣的。」如圖3所示。

圖3 測試**與產品**同源

「配置資訊是指哪些呢?」jared問道。

joe回答道:「配置資訊包括應用程式相關的配置,以及程式部署時的相關配置。應用程式相關的配置是指影響應用程式行為的配置項,比如某個功能的開關、資料庫連線、快取的大小等等。程式部署時的相關配置是指部署在不同機器上的程式元件是如何相互連線的,如ip位址等等。」

「那有些配置資訊是動態生成的,那怎麼把它放到svn中呢?」jared接著問道。

「我們首先要把動態資訊與靜態資訊分開。一般對於動態資訊來說,只要把其變動的規則儲存在svn中就可以了。」alex答道。「比如,某些 ip位址或內部網域名稱是自動配置的,那麼就把自動配置的指令碼放到 svn中就行了。這樣,一旦出了問題,我們也可以確切地知道,所用的分配規則是什麼樣的。」

「那生產環境的配置與測試環境的配置不同,與開發環境的配置也不同,怎麼辦呢?」jared窮追不捨。

「這個好辦,只要存三份配置,對應三種不同的環境就可以了。」joe笑道,「所以,我們**目錄結構是這樣的。」他拿起筆,在紙上畫了一下,如圖4所示。

圖4 以業務為核心組織產品結構

「嗨,joe。這裡的 script目錄裡面放什麼的呢?」jared問道。

「哦,這個目錄是放所有我們用到的指令碼的。」alex笑著說,「以前大家在測試、部署等工作中寫了很多指令碼,用在各自的工作中。現在我們統一放在這 個目錄中,這樣所有人都可以使用相同的指令碼做相同的事情。比如,當開發人員在自己除錯時,只要執行部署指令碼autodeploy,它就會從開發配置目錄 (conf/dev)中讀取相關配置,部署好開發除錯環境。而測試人員使用同乙個部署指令碼autodeploy,它就會從測試配置目錄(conf /test)目錄中讀取相關配置,部署好測試環境,生產環境部署也執行同乙個指令碼,只不過說生產環境配置而已。」

「這樣不錯。我們的指令碼在最終向生產環境部署之前就已經被測試過很多次啦。」jared笑道。

「我們有點跑題了,回到我們最開始遇到的那個測試問題上吧。」jared說,「那個測試失敗,除了功能的小改動以外,log裡還有一些異常,好象是資料格式問題。」

「嗯,這部分測試用到的資料放在乙個固定的共享目錄中了。可是,雖然檔名沒有變化,但其中的資料格式已經改了。也就是說,這份測試**與測試資料存在不一致性。」joe說道。

alex接道,「嗯,我們現在把資料也放到了**倉庫中。」

jared一臉狐疑,問道:「資料那麼大,怎麼放到**倉庫中呢?svn儲存大資料並不高效,而且占用空間也比較大呀。」

「alex 只說了完了一半。其實,我們是把大資料放在了乙個我們自行開發的版本控制系統中了。當把乙份大資料放在其上時,該系統會返回唯一的乙個標識id,我們把它 放在了這個產品**的conf目錄中。這樣,當簽出某個版本的**時,你就可以直接拿到對應的大資料了。如果大資料修改了,那只要把放再次放到那個大資料 儲存系統中,然後把返回的唯一標識更新到對就應的conf目錄中就行了。」joe補充道。「如果沒有這樣乙個大資料庫版本管理系統,也可以使用共享目錄, 只不過,每個子目錄下儲存乙份資料,把這個子目錄位址放在svn裡,也就行了。」

「對於資料庫結構的修改,我們還有另外一種方法,就是利用類似於dbmaintain或是dbdeploy這樣的工具。把每一次資料庫結構的變更都寫到乙個資料庫指令碼,並把它們和**放到一起。這樣,公升級過程就由這些工具就完成了。」

「哦,我明白了。」jared說道,「就是圍繞我們的服務或產品,將所有的東西進行版本管理。這樣,所有的內容都只有唯一的乙個源,所有人都可以拿到同樣的資訊,而且自動化工作也非常容易了。」

「是的。而且,當完成這一步以後,所有的事情自然都成為可跟蹤可追溯的了。」joe笑道:「這也算是乙個額外的收益吧。」

喬梁

持續整合之CruiseControl

持續整合用於定時檢測 構建專案。常用的持續整合工具有cruisecontrol,簡稱cc。那麼我們是如何部署專案到持續整合伺服器中的呢?首先我們可以將我們的專案copy到cc根目下的project目錄下,然後通過在cc根目錄下得config.xml檔案中進行專案配置,具體配置主要參照裡面的demo就...

持續整合(一)

一 提出 整合軟體 的過程不是新問題,如果專案開發的規模比較小,比如乙個人的專案,如果它對 外部系統 的依賴很小,那麼軟體整合不是問題,但是隨著軟體專案複雜度的增加 即使增加乙個人 就會對整合和確保 軟體元件 能夠在一起工作提出了更多的要求 要早整合,常整合 早整合,頻繁的整合幫助專案在早期發現專案...

持續整合簡介

想起我剛畢業後,進入一家以軟體外包為主的外企做開發。它使用傳統的瀑布式的軟體開發流程,沒有使用任何的敏捷實踐。我每天上班開啟電腦,拿到自己的任務,然後從版本控制更新 開啟工程按下build,準備進行今天的開發任務。突然發現build失敗 通常是編譯不過 大喊一聲 誰break build啦 也沒有人...