走向「持續部署」

2021-06-17 21:05:50 字數 3584 閱讀 6814

[收藏]

目前it行業中,似乎「要不要做持續整合?」已經不再是討論的焦點,取而代之的是「如何進行持續整合?」。在前一篇文章中,我介紹了cruise團隊持續整合的演進過程。在最後,還曾提及cruise團隊的持續部署。本文將結合團隊的實際情況,與大家分享持續部署的實踐心得。

「最後一哩」問題

持續整合解決了軟體開發中的部分問題,但還有更為重要的一部分有待解決,即「通過什麼樣的方法,可以讓軟體盡快地在真正的生產環境下執行,從而實現軟體的價值」。在軟體開發過程中,「從功能開發完成開始直到將其部署至生產環境中正式執行」這一階段被稱為「最後一哩」。如果從一開始就對產品發布足夠重視的話,那麼這「最後一哩」可能只需要幾分鐘,甚至幾秒鐘就完成了。然而,事實上大多數專案在這一階段會花上幾個星期,更有甚者可能會是幾個月。

為什麼會這樣呢?對於複雜軟體來說,無論什麼環境中的部署(測試環境,試執行環境,還是生產)都很困難。當軟體第一次被部署到非開發環境去測試,或者當軟體功能及其環境有較大變化時,通常都會暴露出很多問題。而在做使用者驗收測試時,常常會發現更多的問題,例如不能滿足非功能需求,使用者操作不方便,功能與用 戶真正需要的東西相差太遠等等。而開發團隊只有修復這些缺陷後,才能再次部署測試。於是,這個過程會不斷反覆,直至該軟體足夠穩定,才可以部署到生產環境中。

即然部署到測試環境都這麼困難,那麼在生產環境中部署的風險豈不會更大嗎?而且,更為嚴重的是:當生產環境部署出現問題時,擺在你面前的選擇就所剩無幾啦(通常是回滾到以前的狀態,而「回滾」這段時間的停機成本是相當高的)。

上述原因就會導致大多數組織對產品的發布採用「保守策略」,即降低軟體的發布頻率,這也導致兩次發布之間的版本特性差異相對較大。這樣一來,發布風險並未因發布間隔時間加長而降低,反而更高了。當各方面的因素結合在一起時,軟體發布這一環節就變得昂貴而又緩慢啦。而通常「發布過程與頻率」決定了產品在市場中的位置。

那麼,如何更好地解決「最後一哩」這一問題呢?實現持續部署! 即將持續整合實踐擴充套件到整個軟體生命週期頻繁且規律性地自動構建**並將其部署到測試環境中,然後通過一系列的測試,選擇適當的版本部署到預演環境中試執行,最後選擇穩定的版本部署到生產環境中,從而使開發團隊盡早從最終客戶那裡得到反饋,而最終客戶盡早得到軟體的價值。

「持續部署」源於部署時的痛苦

在使用cruise來構建cruise本身以後的第二週後,當我們想再次公升級它時,因沒有事先考慮好公升級方式,結果用了兩人天才把它搞定。從那以後,我們就開始了cruise的持續部署之旅。

持續部署環境

讓持續部署成功的要點

1. 充分而廣泛的自動化測試覆蓋

目前我們的測試包括單元測試、end2end測試、功能測試和效能測試。其中單元測試、end2end測試及功能測試都在同乙個pipeline中,每次**提交都會執行這些測試。而效能測試在另乙個pipeline中,用於每次部署後,收集uat環境和production環境的效能指標。由於部署頻率足夠,我們可以掌握效能資料的微小變化,據此來採取相應的優化措施。

寫單元測試已經成為不爭的事實,自不必說。另外,由於cruise與很多版本管理軟體打交道,這裡所說的end2end測試是指與這些外部介面的測試。而功能測試是指將cruise server和agent真正在測試機器上執行起來後,再執行twist自動化測試套件。我們對功能測試的原則就是每個story都要有功能測試覆蓋,qa與開發人員共用編寫功能測試用例,由開發人員實現之,而且功能測試要讓真實的cruise server和agent進行通訊的基礎上進行。twist是我們公司的另一款產品,用於自動化功能測試,其測試編輯介面如下所示:

2. 盡可能短的測試反饋時間

儘管測試數量較大,測試的絕對執行時間較長,但結合cruise本身提供的並行執行特性,團隊成員胡凱,derek和李彥輝自行開發的測試負載均衡工具(test-load-balancer)將所有測試分成若干份,cruise將其分配到agent集群中同時執行,使單元測試或其它測試在可接受的相對時間內完成(單元測試在15分鐘之內,功能測試在30分鐘之內)。近期還將增加數個agent,以便繼續縮短測試需要的時間。

3. 部署過程自動化

當部署複雜軟體時,都會使用人工過程,而且可能會花上幾天的時間。而這種部署過程通常比較複雜,而且很難可靠地重複操作。因此,人們會寫一些文件幫助這一過程,但文件常常更新不及時。有時,還需要幾個關鍵性人物同時在場才能完成。

當每次由不同的人員進行部署操作時,出錯的概率就增加,所以要盡可能少的人工步驟。

在cruise的pipeline中,儘管由人來觸發兩個環境中的部署,但部署過程本身是自動化的。在部署過程中,cruise的安裝包會自動關閉伺服器,更新自身程式和公升級資料庫,然後再重新啟動。所有的agent也會以server為準,自動更新到與其相同的版本,而不必人工去公升級每個 agent(每次為70個agent的手動公升級也是很大的成本,所以我們做了自動公升級這個特性)。

4. 部署過程要保證資料安全

如果因為持續部署而導致資料丟失或錯誤,會得不償失。所以,我們每次修改資料庫結構或配置檔案的結構後,都會寫出相應的遷移指令碼,並在部署過程中執行。

目前我們使用由thoughtworkers開發的開源專案dbdeploy來做資料庫公升級。對於xml配置檔案的修改,我們也自行開發了乙個遷移框架。

5. 在穩定的前提下,盡早部署

有人會問:「為什麼要持續部署?你又如何知道部署的版本是否穩定呢?宕機了怎麼辦?」的確,沒有哪個開發人員希望持續整合伺服器在工作時間內宕機。儘管我們無法百分之百確保每個部署版本都穩定,但在可預見的範圍內穩定就可以了,否則我們就無法解決「最後一哩」問題。

cruise在最初三個迭代(迭代時間為乙個星期)後,就開始用cruise來做自己的持續整合伺服器了(即uat環境)。我們讓它在uat環境上 執行了兩周,沒有發現什麼問題,說明版本相對穩定,就將它部署到「production」環境上了。在那以後,隨著使用者的增多,很多人認為由於部署失敗而 導致持續整合伺服器宕機的風險要高於那些新特性和修復的缺陷。因此,我們的客戶要求新版本部署至 「production」環境之前,一定要在uat環境上執行。目前,cruise部署到uat環境的頻率不固定(一般為兩天至一周),而部署到 production環境的頻率為一周。也就是說,production環境上的版本要落後於uat一周的時間。

6. 完善的風險緩解措施

隨著專案的進行,難免會有部署失敗的情況,所以一定要有風險緩解措施。例如:

(1) 部署盡可能在使用者少的時候;(2) 部署時必須有技術人員在場;(2) 每次部署前備份原始資料;(3) 時刻準備回滾指令碼。

7. 將同樣的產物部署到不同的環境中

基於這一原則,cruise唯一的配置就是xml檔案。

8. 不斷的反思與重構

這一點就沒有什麼可說的了。它適用於所有的活動。小結

實踐表明,建立自動化部署管道的益處很多。在過去的幾年中,thoughtworks利用這一方法幫助很多專案組和公司解決了他們的「最後一哩」問題。例如,在某專案中,通過自動化部署過程,使部署頻率從幾天一次提高到每天一次,而且該過程耗時少於15中分鐘(其僅有一分鐘的停機時間)。這對軟體整個生命週期的交付階段有著積極作用,只要按下滑鼠就可以準備好所需要測試環境,從而減少了人為失誤造成的不必要的損失,顯著降低軟體發布的風險。另外,頻繁且輕鬆的發布讓開發人員全神貫注於他們想做的事情:開發新的功能。

持續整合 持續交付 持續部署

持續整合 持續整合強調開發人員提交了新 之後,立刻進行構建 單元 測試。根據測試結果,我們可以確定新 和原有 能否正確地整合在一起。持續交付 持續交付在持續整合的基礎上,將整合後的 部署到更貼近真實執行環境的 類生產環境 production like environments 中。比如,我們完成單...

持續整合 持續交付 持續部署

參考 1 continuous integration 持續整合 持續整合強調對於開發人員的每個提交,立刻進行構建 單元 測試。根據測試結果,我們可以確定新 和原有 能否正確地整合在一起。2 continuous delivery 持續交付 持續交付在持續整合的基礎上,將整合後的 部署到更貼近真實執...

持續部署規範

持續交付和持續部署 cd continuous delivery和continuous deployment 的過程即是對之前ci流程中構建的交付物進行自動化部署到開發 測試和生產環境中的過程。以下將對持續交付 持續部署的相關規範進行介紹。在應用部署實施之前,devops會自動備份應用安裝包,如 w...