張曉帆,劉 寧,潘 帆
(1.中國(guó)電子科技集團(tuán)第10研究所,四川 成都 610036;2.四川大學(xué) 電子信息學(xué)院,四川 成都 610207)
作為敏捷軟件開(kāi)發(fā)的核心實(shí)踐,持續(xù)集成/持續(xù)交付向開(kāi)發(fā)和交付團(tuán)隊(duì)提供及時(shí)有效的反饋,以持續(xù)提升開(kāi)發(fā)和交付的效率和質(zhì)量[1-3]。持續(xù)集成/持續(xù)交付成功實(shí)踐的關(guān)鍵在于開(kāi)發(fā)/測(cè)試/交付團(tuán)隊(duì)間的緊密合作。然而,不同的團(tuán)隊(duì)具有不同的背景和領(lǐng)域知識(shí),因此緊密合作要求集成/交付相關(guān)信息高效地傳遞到正確的團(tuán)隊(duì)/人員,以便在正確的時(shí)間采取正確的行動(dòng)?!案咝А钡臏贤ㄔ谥行突虼笮徒M織中始終是一個(gè)挑戰(zhàn),而將持續(xù)集成/持續(xù)交付過(guò)程進(jìn)行“可視化”將大大有助于信息的高效傳遞。
目前,對(duì)持續(xù)集成/持續(xù)交付的研究主要集中于對(duì)集成/交付步驟和各步驟相關(guān)工具的研究,對(duì)全過(guò)程可視化的研究相對(duì)較少。文獻(xiàn)[4-5]提出了由開(kāi)發(fā)集成,驗(yàn)收測(cè)試,部署發(fā)布構(gòu)成的持續(xù)交付基本過(guò)程,并提出了對(duì)全過(guò)程進(jìn)行監(jiān)控的概念。文獻(xiàn)[6]提出了由構(gòu)建,單元測(cè)試,集成測(cè)試,驗(yàn)收測(cè)試構(gòu)成的持續(xù)交付的驗(yàn)證步驟。文獻(xiàn)[7]提出了DevOps常用的CI/CD工具集合。文獻(xiàn)[8]提出了通過(guò)可視化方法,對(duì)敏捷團(tuán)隊(duì)中各成員的貢獻(xiàn)進(jìn)行統(tǒng)計(jì)和呈現(xiàn)。
針對(duì)上述問(wèn)題,文中提出一種持續(xù)集成(CI)/持續(xù)交付(CD)的可視化設(shè)計(jì)體系和方法,包括:哪些信息需要可視化;信息如何可視化;信息如何被動(dòng)或主動(dòng)地傳遞到合適的團(tuán)隊(duì);在發(fā)現(xiàn)問(wèn)題時(shí),相應(yīng)團(tuán)隊(duì)該如何采取行動(dòng)。同時(shí),提出該“可視化”系統(tǒng)的實(shí)現(xiàn)架構(gòu)參考,包括由業(yè)界主流開(kāi)源軟件Jenkins、BitBucket、Jira等工具組成的系統(tǒng)架構(gòu)。該體系設(shè)計(jì)和架構(gòu)有效地將各種信息呈現(xiàn)或推送給相關(guān)人員,提升了持續(xù)集成/持續(xù)交付的實(shí)施效率,幫助團(tuán)隊(duì)有效提升了開(kāi)發(fā)和交付的質(zhì)量和效率。
持續(xù)集成/持續(xù)交付系統(tǒng)的可視化體系設(shè)計(jì)如圖1所示。
圖1 CI/CD可視化視圖
該體系由兩部分構(gòu)成:
持續(xù)集成(CI)狀態(tài)視圖:該部分主要向開(kāi)發(fā)團(tuán)隊(duì)傳遞集成過(guò)程相關(guān)信息。對(duì)比文獻(xiàn)[9-10],文中提出了CI排隊(duì)過(guò)程和隊(duì)列視圖。
持續(xù)集成(CI)/持續(xù)交付(CD)健康視圖:該部分主要向開(kāi)發(fā)/測(cè)試/交付團(tuán)隊(duì)傳遞產(chǎn)品交付相關(guān)信息。文中提出了CI/CD核心階段和擴(kuò)展階段的概念,并針對(duì)不同階段的重要程度和反饋成本,提出了多種系統(tǒng)同步和可視化通知手段。
該部分顯示了對(duì)開(kāi)發(fā)團(tuán)隊(duì)很重要的CI狀態(tài)信息,包括請(qǐng)求排隊(duì)狀態(tài)和集成流水線狀態(tài)。典型的CI過(guò)程如圖2所示,包括排隊(duì)階段和流水線階段。
圖2 CI排隊(duì)和流水線
(1)CI隊(duì)列視圖。
在中等規(guī)模的組織(約100個(gè)開(kāi)發(fā)工程師)中,考慮每個(gè)CI持續(xù)時(shí)間為10分鐘,如果每個(gè)工程師每日提交集成請(qǐng)求,則集成請(qǐng)求將不得不在CI系統(tǒng)中排隊(duì)以依次處理。
CI隊(duì)列視圖可以讓每個(gè)工程師知道CI系統(tǒng)的繁忙程度,了解CI系統(tǒng)是否接受了集成請(qǐng)求,并預(yù)測(cè)何時(shí)可以處理該集成請(qǐng)求。因此,CI相關(guān)的信息都應(yīng)在此展示,如圖3,包括請(qǐng)求提交者名稱、提交者時(shí)間以及為集成提交的分支。
圖3 CI隊(duì)列視圖
(2)CI流水線視圖。
如圖4,該視圖讓每個(gè)工程師知道其集成請(qǐng)求處理的狀態(tài),不同的顏色給出了CI流水線各步驟的不同狀態(tài)。典型的CI步驟包括:系統(tǒng)空閑→構(gòu)建→UT→IT→內(nèi)部發(fā)布。
圖4 CI流水線視圖
當(dāng)某步驟失敗時(shí),CI系統(tǒng)該如何處理?不同的團(tuán)隊(duì)有不同的看法,有團(tuán)隊(duì)建議暫停CI流水線并向團(tuán)隊(duì)發(fā)出警報(bào),有團(tuán)隊(duì)建議直接回滾版本并給提交者以提示。根據(jù)筆者數(shù)年的實(shí)踐經(jīng)驗(yàn),總結(jié)該部分的設(shè)計(jì)如下:
·如果該系統(tǒng)服務(wù)于一個(gè)小團(tuán)隊(duì),集成系統(tǒng)的吞吐量不會(huì)成為問(wèn)題,團(tuán)隊(duì)的溝通和立即行動(dòng)是可行的。在這種情況下,CI失敗時(shí),可以選擇暫停CI流水線并向團(tuán)隊(duì)發(fā)出警報(bào)。
·如果該系統(tǒng)服務(wù)于中/大規(guī)模的團(tuán)隊(duì),則集成系統(tǒng)吞吐量將成為問(wèn)題。與此同時(shí),大中型團(tuán)隊(duì)的溝通問(wèn)題會(huì)更加嚴(yán)重,團(tuán)隊(duì)成員對(duì)集成時(shí)發(fā)現(xiàn)的問(wèn)題的響應(yīng)會(huì)更為遲緩。在這種情況下,CI系統(tǒng)自動(dòng)回退版本并給提交者以提示,騰空CI系統(tǒng)以使系統(tǒng)可以處理下一位工程師的集成請(qǐng)求。這種方式可以使集成系統(tǒng)保持高吞吐量,以提升中/大規(guī)模團(tuán)隊(duì)的持續(xù)集成效率。
該部分視圖呈現(xiàn)每個(gè)版本的CI/CD健康狀況,開(kāi)發(fā)/測(cè)試/交付團(tuán)隊(duì)都應(yīng)該關(guān)注該部分呈現(xiàn)的信息:
·開(kāi)發(fā)/測(cè)試團(tuán)隊(duì)?wèi)?yīng)采取行動(dòng)解決測(cè)試中發(fā)現(xiàn)的各種問(wèn)題;
·交付團(tuán)隊(duì)可以根據(jù)各版本的健康狀況,選擇合適的版本以進(jìn)行交付。
每個(gè)版本的CI/CD過(guò)程也是一個(gè)流水線。該流水線通常有4個(gè)階段,如圖5所示。
圖5 版本CI/CD流水線視圖
(1)持續(xù)集成(CI)核心階段:build/UT/IT。
該部分呈現(xiàn)了build/UT/IT的健康狀態(tài)。
此階段中的任何步驟失敗都將導(dǎo)致CI失敗。如果發(fā)生任何失敗,都不會(huì)進(jìn)行新版本(內(nèi)部)發(fā)布,并且主干版本將回滾到最后一次成功發(fā)布的版本,并將郵件發(fā)送給提交者以指示失敗原因。
(2)持續(xù)集成(CI)擴(kuò)展階段:代碼靜態(tài)檢查。
此階段主要完成代碼的靜態(tài)檢查,包括build warning,或通過(guò)lint工具進(jìn)行的代碼規(guī)范靜態(tài)檢查,如文獻(xiàn)[11]。如果此階段中的步驟失敗,流水線不會(huì)終止,但開(kāi)發(fā)團(tuán)隊(duì)會(huì)收到一封警告郵件。
工程師需要從CI獲得快速反饋,需要通過(guò)CI在每天進(jìn)行多次構(gòu)建和軟件測(cè)試,因此單次CI的時(shí)間需要縮短。對(duì)于某些不太重要,并且耗時(shí)的驗(yàn)證步驟,如代碼靜態(tài)檢查,或代碼圈復(fù)雜性分析,都可以將其置于擴(kuò)展階段。由于這些驗(yàn)證處于擴(kuò)展階段而非核心階段,當(dāng)在此階段檢查出問(wèn)題時(shí),比如引入大量新構(gòu)建警告時(shí),因?yàn)闆](méi)有版本回退機(jī)制,開(kāi)發(fā)團(tuán)隊(duì)可能會(huì)也可能不會(huì)修復(fù)這些問(wèn)題。筆者在過(guò)去幾年遇到了這個(gè)問(wèn)題:越來(lái)越多的build warning被引入集成主線,而沒(méi)有人采取行動(dòng)。因此,在可視化設(shè)計(jì)中,將擴(kuò)展階段的結(jié)果公示到整個(gè)團(tuán)隊(duì),讓整個(gè)團(tuán)隊(duì)知道誰(shuí)在哪個(gè)版本引入新警告,使得提交者有壓力不要引入build warning或盡快修復(fù)它們。
(3)持續(xù)交付(CD)核心階段:驗(yàn)收測(cè)試(user acceptance test)。
此階段從產(chǎn)品交付的角度,進(jìn)行驗(yàn)收測(cè)試。如文獻(xiàn)[12-13],驗(yàn)收測(cè)試通常自動(dòng)化進(jìn)行。如果驗(yàn)收測(cè)試通過(guò),該版本可以進(jìn)行發(fā)布。如果驗(yàn)收測(cè)試失敗,整個(gè)CI/CD系統(tǒng)將被暫停,并向開(kāi)發(fā)團(tuán)隊(duì)進(jìn)行紅色警報(bào),以便推動(dòng)開(kāi)發(fā)團(tuán)隊(duì)及時(shí)修復(fù)在驗(yàn)收測(cè)試中發(fā)現(xiàn)的問(wèn)題。
通常,從用戶角度進(jìn)行的驗(yàn)收測(cè)試會(huì)耗費(fèi)較長(zhǎng)時(shí)間,比如1~2小時(shí)或更長(zhǎng)??紤]到CI的典型持續(xù)時(shí)間為10分鐘,對(duì)每個(gè)通過(guò)CI的版本進(jìn)行驗(yàn)收測(cè)試是不可行的。在該系統(tǒng)中,采用異步機(jī)制以處理CI過(guò)程和驗(yàn)收測(cè)試過(guò)程難以同步的問(wèn)題:驗(yàn)收測(cè)試輪詢最新(內(nèi)部)發(fā)布的CI版本以開(kāi)始測(cè)試,這里某些CI版本可能被“繞過(guò)”,如圖6所示。
圖6 異步執(zhí)行長(zhǎng)時(shí)間的驗(yàn)收測(cè)試
因?yàn)镃I和驗(yàn)收測(cè)試采用了異步的設(shè)計(jì),在驗(yàn)收測(cè)試失敗的情況下,集成流水線該如何進(jìn)行?如圖6,如果AT2失敗,系統(tǒng)如何處理,如何向用戶進(jìn)行反饋。通常解決方法有3種:
·通過(guò)郵件指示失敗,并且CI/CD系統(tǒng)繼續(xù)處理新的CI請(qǐng)求。
·V2失敗,則回退以使用V1進(jìn)行驗(yàn)收測(cè)試。
·暫停整個(gè)流水線直到AT2失敗的問(wèn)題修復(fù),并向整個(gè)團(tuán)隊(duì)及時(shí)告警通知。
根據(jù)實(shí)踐,方法1存在開(kāi)發(fā)團(tuán)隊(duì)沒(méi)有動(dòng)力/壓力來(lái)解決AT故障的問(wèn)題,因?yàn)殚_(kāi)發(fā)團(tuán)隊(duì)的新CI請(qǐng)求可以繼續(xù)處理。當(dāng)越來(lái)越多的新CI請(qǐng)求集成入主線時(shí),主線版本的質(zhì)量持續(xù)惡化。方法2也有一些限制:首先,它使系統(tǒng)更復(fù)雜,其次,它加長(zhǎng)了反饋周期,因?yàn)樗枰L(zhǎng)時(shí)間重新運(yùn)行V1的AT。方法3是最終使用的方法,當(dāng)AT2失敗時(shí),系統(tǒng)會(huì)自動(dòng)采取3項(xiàng)行動(dòng),迫使開(kāi)發(fā)團(tuán)隊(duì)立即采取行動(dòng)以修復(fù)問(wèn)題:
①CI系統(tǒng)將被暫停,開(kāi)發(fā)團(tuán)隊(duì)不能再提新的CI請(qǐng)求,迫使開(kāi)發(fā)團(tuán)隊(duì)必須采取行動(dòng);
②郵件將廣播給開(kāi)發(fā)團(tuán)隊(duì),提示驗(yàn)收測(cè)試(AT)在V1或V2版本失敗,CI系統(tǒng)暫停;
③系統(tǒng)將可視化“紅色警報(bào)”,如圖7所示。
圖7 可視化“紅色警報(bào)”(針對(duì)驗(yàn)收測(cè)試失敗)
(4)持續(xù)交付(CD)擴(kuò)展階段:可靠性測(cè)試(reliability test)。
不僅可靠性測(cè)試,其他測(cè)試,如性能測(cè)試、探索測(cè)試等也可以在該階段進(jìn)行。
如果擴(kuò)展階段的驗(yàn)證失敗,則應(yīng)在問(wèn)題跟蹤系統(tǒng)(如Jira)中記錄和跟蹤問(wèn)題,以便開(kāi)發(fā)團(tuán)隊(duì)可以跟進(jìn)。如果可靠性測(cè)試通過(guò),對(duì)于交付團(tuán)隊(duì),該版本將是更有信心的候選交付版本??煽啃詼y(cè)試的典型持續(xù)時(shí)間為1~2天,因此,與CI和驗(yàn)收測(cè)試的異步設(shè)計(jì)類似,可靠性測(cè)試也以異步方式運(yùn)行:并非所有通過(guò)驗(yàn)收測(cè)試的版本都會(huì)進(jìn)行可靠性測(cè)試,可靠性測(cè)試將輪詢通過(guò)驗(yàn)收測(cè)試的最新版本以進(jìn)行測(cè)試,并且可以繞過(guò)某些版本。
表1總結(jié)了CI/CD系統(tǒng)的可視化反饋/指示,以及各團(tuán)隊(duì)所需的響應(yīng)。
表1 CI/CD可視化總結(jié)
可視化系統(tǒng)的實(shí)現(xiàn)架構(gòu)參考如圖8所示。
圖8 可視化系統(tǒng)架構(gòu)設(shè)計(jì)
可視化服務(wù)是采用NodeJS框架的Web服務(wù),用于顯示CI/CD的狀態(tài)和數(shù)據(jù)。
如文獻(xiàn)[14],CI/CD系統(tǒng)由多種子系統(tǒng)構(gòu)成,其核心為Jenkins。Jenkins提供了流水線功能,并提供了CI/CD系統(tǒng)可視化所需的數(shù)據(jù)。
(1)可視化服務(wù)需要查詢Jenkins的數(shù)據(jù),如提交者名稱,時(shí)間,構(gòu)建和測(cè)試結(jié)果的種類。
Node.js提供了一個(gè)模塊和接口,以查詢Jenkins的數(shù)據(jù)。下面是數(shù)據(jù)查詢樣例代碼片段:
var jenkinsapi=require('jenkins-api');
# Get last build
var jobName='Jenkins-build-jobs'
jenkinsapi.last_build_info(jobName, function(err, data) {
callback(err,data);
});
# Get one specific build
var jobName='Jenkins-build-jobs';
var buildNum=10;
jenkinsapi.build_info(jobName, buildNum,function(err, data) {
callback(err,data);
});
通過(guò)查詢接口,如下JSON格式的數(shù)據(jù)將從Jenkins返回Node.js的模塊。
"builds" :
{
"buildNumber" : 294,
"duration" : "4 min",
"icon" : "blue.png",
"jobName" : "A-Jenkins-BuildJob",
"parentBuildNumber" : 384,
"parentJobName" : " A-Jenkins-BuildJob-Parent",
"phaseName" : " Build",
"result" : "SUCCESS",
"url" : "url for the Jenkins job"
},
其后,可視化服務(wù)解析數(shù)據(jù),并按設(shè)計(jì)顯示CI/CD的狀態(tài)和數(shù)據(jù)。
(2)可視化系統(tǒng)還提供了到Jira的超鏈接。所有團(tuán)隊(duì)都可以通過(guò)超鏈接直達(dá)Jira,以報(bào)告反饋/問(wèn)題。
作為最流行的CI/CD工具,Jenkins具有強(qiáng)大的集成功能,以與各種構(gòu)建/測(cè)試/通知系統(tǒng)互通:
·在該架構(gòu)中,BitBucket用作版本控制系統(tǒng)。BitBucket是私有Git倉(cāng)庫(kù),用于存儲(chǔ)來(lái)自開(kāi)發(fā)團(tuán)隊(duì)的代碼,通過(guò)其WebHook,BitBucket可以在某個(gè)分支上發(fā)生提交時(shí)觸發(fā)Jenkins作業(yè)。如文獻(xiàn)[15],Jenkins從BitBucket中獲取代碼更改,并進(jìn)行本地構(gòu)建。
·使用構(gòu)建輸出,Jenkins與測(cè)試系統(tǒng)接口。測(cè)試系統(tǒng)的參考是CppUnit+labview。 CppUnit適用于UT/IT。它可以在非目標(biāo)環(huán)境中高效運(yùn)行。對(duì)于驗(yàn)收測(cè)試和可靠性測(cè)試,由于需要真實(shí)的目標(biāo)環(huán)境,labview可用于鏈接和控制各種設(shè)備進(jìn)行自動(dòng)測(cè)試。
·當(dāng)獲得測(cè)試結(jié)果時(shí),Jenkins可以與郵件系統(tǒng)連接以通知團(tuán)隊(duì),并將失敗作為問(wèn)題記錄入輕量級(jí)問(wèn)題跟蹤工具Jira。
提出了一種持續(xù)集成/持續(xù)交付系統(tǒng)的可視化體系設(shè)計(jì)和參考架構(gòu)。該設(shè)計(jì)將各種信息在不同的視圖進(jìn)行合理組織,將信息呈現(xiàn)或推送給最相關(guān)人員,并建議了團(tuán)隊(duì)在各種情況下應(yīng)該采取的行動(dòng)。該設(shè)計(jì)連接了開(kāi)發(fā)/測(cè)試團(tuán)隊(duì)和產(chǎn)品交付團(tuán)隊(duì),有效在團(tuán)隊(duì)中共享信息,促進(jìn)團(tuán)隊(duì)協(xié)作,高效持續(xù)集成以持續(xù)交付高質(zhì)量的產(chǎn)品。
可視化是持續(xù)交付的重大進(jìn)步,而探索永遠(yuǎn)不會(huì)停止。持續(xù)交付仍有許多機(jī)遇和挑戰(zhàn):CI/CD系統(tǒng)在展示數(shù)據(jù)的同時(shí),會(huì)記錄大量數(shù)據(jù)。如何利用這些數(shù)據(jù)以不斷改進(jìn)系統(tǒng)本身和開(kāi)發(fā)/交付過(guò)程,這是一個(gè)可以進(jìn)一步探索的主題。當(dāng)軟件準(zhǔn)備交付時(shí),可以進(jìn)一步為最終用戶進(jìn)行持續(xù)部署。然而,對(duì)于嵌入式設(shè)備/系統(tǒng)來(lái)說(shuō),持續(xù)部署將是一個(gè)巨大的挑戰(zhàn),當(dāng)成百上千個(gè)設(shè)備通過(guò)有線或無(wú)線連接分布在不同位置時(shí),可以想象將新軟件部署/升級(jí)到每個(gè)設(shè)備的難度。該難題也是可以進(jìn)一步探索的主題。