天天看點

談談企業的持續傳遞流水線設計

談談企業的持續傳遞流水線設計

本文講的是談談企業的持續傳遞流水線設計,有一天,業務人員急沖沖的跑過來,對你說生産上出現了一個嚴重BUG,必須要盡快修複。你聽完問題描述後,胸有成竹坐定并迅速定位問題,随後改動了一行代碼并送出,系統開始自動編譯、各個環境自動化測試、釋出上線。幾分鐘後,生産環境上該BUG已經被修複掉。

上面所提到的場景,這是不是很美妙?但是想必不少讀者要忍不住要吐槽了,這太不實際了:新功能上線測試不要時間麼?新增了功能肯定要做回歸測試,這都需要一定的時間。況且怎麼可以随便部署上線?還得通過預發演練、走釋出審批流程。其實這些過程大家也都清楚,那麼不妨從另一個角度思考下,是否可以把這個過程中所有需要人工線下操作的環節都通過一個平台自動化實作掉呢?

這些其實都是本文要為大家一一解讀的,事實上上述的例子雖然有些理想化,但是卻可以作為一個終極目标,并非沒有實作的可能。

本文目錄:

一、什麼是持續傳遞?

二、設計持續傳遞四大關鍵要素

三、落地持續傳遞五大注意事項

四、總結

首先來了解下持續傳遞的概念,在維基百科中持續傳遞的定義如下:

持續傳遞(Continuous delivery,縮寫為 CD),是一種軟體工程方法,讓軟體産品的産出過程在一個短周期内完成,以保證軟體可以穩定、持續的保持在随時可以釋出的狀況。它的目标在于讓軟體的編譯、測試與釋出變得更快更頻繁。這種方式可以減少軟體開發的成本與時間,減少風險。

好吧,看定義總是很抽象的,我們從兩個次元來了解持續傳遞,一個是範圍,一個是宗旨。

先說說範圍,軟體研發的生命周期大家想必都很了解,大緻包括如下幾個階段,需求、設計、建構(包括開發、編譯)、測試(系統內建測試、使用者驗收測試、非功能性測試)、釋出上線。

談談企業的持續傳遞流水線設計

持續內建覆寫建構、測試兩個階段,關注于代碼的送出、編譯、測試。持續部署意在保障每一個代碼送出,都能自動化的部署到生産環境上;持續傳遞和持續部署有些類似,而是保障從原始需求到最終傳遞上線全過程的穩定可靠,但是不強求自動化部署到生産環境上,在最終釋出上線時,可以人工介入,也可以自動部署。

再看看持續傳遞的宗旨,持續傳遞的核心宗旨是:保證每次送出代碼都産生一個可釋出的版本。下圖是持續傳遞的一個核心流程圖,代碼送出觸發建構和單元測試,完成後觸發自動化測試,根據自動化測試的結果進行審批是否進行使用者驗收測試,使用者驗收測試通過後進行釋出上線。中間每一個環節都會産生回報,一旦失敗就終止目前傳遞流程。

談談企業的持續傳遞流水線設計

通過這範圍和宗旨兩方面,是否已經有些了解持續傳遞是什麼了呢?還是有些泛?不急,接下來我們針對持續傳遞的整個流程進行拆分。

從代碼送出開始,我們可以把整個持續傳遞歸納出四個關鍵要素:持續內建、自動化測試、自動化部署、流水線。

持續內建

在傳統瀑布開發模式下,通常很長一段時間内,代碼都是不穩定且不可用的;待到功能開發完畢了,才會進入內建階段,這時問題出現了:團隊規模越大,要開發的需求越多,這個周期就越長,內建階段花費的代價也就越大,項目風險也越大,項目的進度極不可控。

而在靈活過程中,将代碼開發和內建按子產品拆分成多個小階段,每一階段完成後都會進行內建,這在一定程度上減少了風險。

持續內建要求代碼的開發和功能內建并行進行,相輔相成,要求至少做到每日編譯甚至代碼送出即觸發編譯。建構時會對整個應用的所有子產品進行編譯,并伴随單元測試以及代碼品質分析等動作。如果編譯失敗了或者單元測試失敗了,那麼必須要立即修複問題,直到建構成功。總之,要求代碼庫的代碼持續處于可用狀态。

持續內建的時間一定要盡可能的短,尤其是代碼送出觸發建構的場景下。否則試想:一支20餘人的開發團隊,每次建構(編譯+單元測試+代碼品質分析)需要花費20多分鐘;而每次代碼送出時觸發建構,會産生大量的編譯任務排隊,并且會不停增加;編譯發生問題時較難定位,因為在上次開始編譯到這次編譯中間,會有多人送出,很難快速确認是由誰的送出導緻的編譯失敗。

持續內建的時間通常建議在5分鐘以内,90秒内完成是極好的。是以對于代碼的編譯、單元測試都一定要注意時間。在分布式場景下,應用可能會依賴于很多外部應用或者中間件,單元測試不一定非要連通真實環境,會帶來請求響應時間的損耗,并且一般也要求單元測試可以在離線環境下可執行,是以可以采用Mock的方式,提升單元測試速度。同樣,由于要控制每次建構的時間,不建議在持續內建流程中去做內建測試(SIT),這個可以交給集測流水線去處理,由測試人員在內建測試環節繼續跟進。

持續內建保證了代碼始終是可用的,編譯正确并且通過所有單元測試。這是持續傳遞流水線的第一步。

自動化測試

在整個軟體過程中,測試可以分為兩類:功能測試(冒煙測試、系統內建測試(SIT)、使用者驗收測試(UAT))、非功能性測試(壓力測試、穩定性測試、安全測試)等。非功能性測試姑且不論,功能性測試如系統內建測試、使用者驗收測試等都需要盡可能地覆寫所有的功能子產品,功能越是複雜的應用系統,測試起來的工作量也越大。

雖然自動化測試的理念已經普及了好多年,但是大部分企業内部,還是以手工測試為主,甚至大部分企業,對手工測試的投入也都是不足的。原因有很多,比如人員缺乏和時間周期緊張,來不及寫自動化測試腳本,或者測試人員的水準不足等。這些确實都是客觀存在的原因,但是這樣真的是節省了成本嗎?事實上對于持續發展的産品而言,每次釋出時都需要大量的人力投入去進行測試,會有大量重複的測試工作,釋出的次數越多,成本越高,某種程度上這甚至限制了快速頻繁釋出的能力,由于人力資源的限制,很多企業回歸測試時,隻能相信開發人員對于功能調整影響範圍的預估,縮小回歸測試的範圍,為線上運作帶來了極大的風險。在《持續傳遞》一書中看到這樣一個數字:某組織每次釋出軟體是花費在手工測試上的錢就有300萬美元。自動化測試帶來的價值也絕對值得上現在的投入。

想要實作整個持續傳遞流水線的自動化,實作本文一開始的那個例子,全面的自動化測試不可或缺。隻需要花費幾分鐘至幾十分鐘,通過了各個環境的自動化測試,便相當于對品質打上了合格标簽。可以選擇直接部署到生産環境上,或者等待晚上某個時間點進行上線部署。

傳遞流水線

持續傳遞是一個大流程,從代碼送出一直到部署上線,但是我們在實踐過程中發現,這種大流程,未免太大太笨重。在企業真實的情況下,大流程本身沒問題,但是其中的環節往往沒有這麼簡單,想要讓這個流水線真正能被企業實際使用,還要對大流程進行拆分。我們在實踐中把持續傳遞流水線拆分成三個子流水線:開發流水線、集測流水線、釋出流水線。

開發流水線:

面向開發人員和開發環境。開發人員送出代碼,觸發建構,部署到開發環境中由開發人員進行自測。這個流水線在開發的過程中會頻繁進行。

集測流水線:

面向測試人員,同樣以建構為開始,基于建構的産物(部署媒體),部署到內建測試環境,進行系統內建測試。

釋出流水線:

當次釋出的所有需求全部通過系統內建測試後,便可以進入後續測試如使用者驗收測試、非功能性測試等,通過後,則認為已經達到釋出上線标準,觸發上線申請審批流程,審批通過可以進行自動化釋出上線。

在項目中,開發流水線的觸發頻率最高,集測流水線其次,釋出流水線觸發的頻率最低。

将整個的持續傳遞流水線拆分為三個子流水線,可以做到面向不同的角色,這樣更靈活也更便于使用。當然,不同企業的流程也是有着差別的,不一定嚴格按照這三個流水線。即使定義成這三個流水線,每個流水線的流程和環節也是不同的,可以結合自己企業的實際流程來拆分。

上面說了很多理論,理論終究要落地實踐,流程和關鍵環節也已經比較清楚了,但是在實際落地時還是會有很多問題和細節點需要注意。先思考下幾個問題:

如何快速支援流程使用過程中的一些微調(如環節的配置字段屬性等)?

如何做到流程手工和自動執行的自定義?

如何讓每個環境部署的媒體對應的是哪次代碼送出、哪個傳遞物有迹可循?

如何直覺的檢視傳遞流程目前到了哪個環節、每個環節的狀态是什麼樣的?

如何以環境為視角,看到該環境下正在運作哪些應用?

帶着上面幾個問題,我們在實踐的過程中,梳理出如下幾個持續傳遞能力落地的關鍵點:

安全

傳遞流水線的核心是驅動開發、測試、運維、品質等多個部門和角色進行協作,涉及衆多的角色和功能、又囊括了各個環境的部署運維操作,安全問題自然不容忽視。

明确責任人:流程中每個環節都要有責任人,在人工執行時,隻有該責任人才能執行該環節,同時每個環節執行資訊都要有詳細的記錄和展現,如:操作人、開始時間、結束時間、自動化執行時間等。

環境類型授權:而由于自動化部署的支撐,對于每個環境的部署都可以通過平台一鍵執行。開發、測試環境尚還好,但是對于預發、生産環境的部署,一般要由運維人員來操作。對于環境類型的細分授權,在人工執行的時候,會更加安全。

釋出審批流程:事實上,在企業内部,正常釋出上線通常需要經曆應用釋出審批流程,在生産部署前,根據釋出的類型(如正常釋出、緊急釋出)等來觸發不同的上線審批流程,完成上線審批後,才可以執行部署上線的動作。具體的流程可以結合企業内部實際的流程。

流程支援環節、屬性自定義

理論上說,一個企業的持續傳遞流程應該是一緻并且基本穩定的,但實際上大部分企業内部不止一套流程,不同部門、不同項目組的過程體系甚至都可能是不同的,姑且不論這種情況的對與錯,在尚未統一流程和過程前,這種情況總歸是要考慮支援的。即使統一了流程,随着企業的不斷發展,流程的一些細節也會持續變化,如一些環節的屬性配置等。是以對于流程的環境、屬性自定義、可動态擴充等能力在設計時是要重點關注的。

保持部署媒體不變,便于追溯

很多企業由于規範的不标準,經常會出現最終上線使用的部署媒體和系統內建測試、使用者驗收測試的部署媒體有所不同。比如在使用者驗收測試階段,發現了一個問題,有可能開發人員改動後直接打一個包進行部署上線,不再通過系統內建測試,或者通過人為的判斷改動影響範圍,進行小範圍測試。這些都帶來了很大的生産隐患。

從标準來說,從系統內建測試開始,後面所有環境應該用的都是同一個媒體。在系統內建測試的一開始,進行代碼建構,得到部署媒體。該媒體位址在整個流水線上下文中進行傳遞,後面每個環境的部署都采用該媒體。如果把集測流水線和釋出流水線分離開,釋出流水線必須要關聯一個內建測試流水線,在釋出流水線中的環境部署,采用集測流水線中的媒體,依舊維持媒體一緻。如果發現問題需要進行修複,必須要從集測流水線重新開始。對于媒體可以使用nexus等媒體倉庫進行統一管理。

直覺的協作看闆

一個流水線有多個角色協作參與,從實際參與者視角出發也好、管理者視角出發也罷,都需要一個直覺的看闆,來整體檢視每個應用目前的傳遞進度,目前處于哪個環節(系統內建測試、使用者驗收測試環境、預發、生産),以及成功和失敗情況。我們提供了兩種看闆:釋出看闆、環境看闆。釋出看闆基于産品、微服務的角度,檢視每個産品版本在不同環境上的部署情況。展現産品版本、産品修訂版本、産品釋出版本、産品的微服務及其版本。

談談企業的持續傳遞流水線設計

環境看闆則是從環境的次元,檢視每個環境下有哪些應用的哪些版本部署了。如下圖所示:

談談企業的持續傳遞流水線設計

不要一味的自動化,自動和人工要結合

回過頭來看,文章開篇的例子并非不可達成,但是要求很高,需要成熟的持續內建體系、完整覆寫的的自動化測試傳遞,全面的自動化部署能力的支撐,想達到這一步,自然不是一時之功就可以的。在建設的過程中,是少不了人工介入流水線中具體環節的,尤其是測試環節。是以在流水線的設計時,要充分考慮人工執行和自動執行的自定義,如果自動執行失敗的話,也要提供人工介入的入口,允許人工選擇重新執行、終止流程等動作。

以這些為基礎準則,我們底層基于了普元的BPS流程引擎,支撐流程的自定義和擴充。并且,針對于每個環節,都可以配置前置後置事件、人工執行還是自動執行,責任人等。整個流水線從建構開始,以代碼的buildNumber貫穿全流程。便于問題、進度的追溯。效果圖如下:

談談企業的持續傳遞流水線設計

最後再回頭看看開篇的例子,在建設企業的持續傳遞流水線時,能做到全自動化固然很好,但并非是要立刻實作全自動化的效果,這也不現實。初期首先是結合企業的标準流程和規範,将企業的持續傳遞流水線打通。可以自動化的環節盡量做到自動化,尚且做不到自動化的就人工介入。

畢竟持續傳遞的價值絕不僅僅是快,對于大多數企業而言,在提升軟體傳遞效率之外,統一企業的軟體傳遞流程和規範、保證軟體傳遞品質、降低軟體釋出風險,這才是最重要的。

原文釋出時間為: 2017-07-25

本文作者:王海龍

本文來自雲栖社群合作夥伴EAWorld,了解相關資訊可以關注EAWorld。