李 強(qiáng),成俊峰
(1.上汽通用汽車有限公司武漢分公司,湖北 武漢 430200;2.泛亞汽車技術(shù)中心有限公司,上海 201208)
隨著汽車智能化的快速發(fā)展,“軟件定義汽車”在產(chǎn)業(yè)中已成為共識(shí)。同時(shí)在汽車產(chǎn)業(yè)軟硬件解耦的大趨勢下,軟件的結(jié)構(gòu)占比也將進(jìn)一步提升。汽車軟件的OTA(Over the Air Technology,空中下載技術(shù))也對軟件版本快速迭代和持續(xù)升級(jí)提供了支持,隨著智能化、網(wǎng)聯(lián)化、電動(dòng)化程度的進(jìn)一步加深,汽車軟件的代碼量必將進(jìn)一步提高。過去一輛汽車包含1000萬行軟件代碼,目前一輛車已經(jīng)擁有了1億行的代碼量,隨著代碼跨車型、跨平臺(tái)、跨車企重用功能的進(jìn)一步發(fā)展,以及自動(dòng)駕駛技術(shù)的越來越成熟,必將進(jìn)一步推動(dòng)代碼量快速增長。傳統(tǒng)的瀑布軟件開發(fā)模型已經(jīng)不能適應(yīng)汽車軟件快速迭代的發(fā)展要求。2001年,敏捷軟件開發(fā)方法誕生,持續(xù)集成作為“敏捷基礎(chǔ)設(shè)施”也在不斷發(fā)展,搭建一個(gè)安全的持續(xù)集成平臺(tái),制定適合于項(xiàng)目的高效持續(xù)集成策略,將對軟件開發(fā)的效率產(chǎn)生深遠(yuǎn)影響。
CI(Continuous Integration,持續(xù)集成)工具的選擇種類繁多,各種工具也沒有絕對的好壞,首先需要考慮的是選擇什么樣的服務(wù)器進(jìn)行工具鏈的搭建。市場上購買云服務(wù)器服務(wù)還是決定創(chuàng)建自己的服務(wù)器環(huán)境來搭建,都需要根據(jù)公司的戰(zhàn)略部署和投入來進(jìn)行綜合評估,無論傾向于哪種方式,對持續(xù)集成工具鏈本身沒有太大影響。
在選擇搭建系統(tǒng)時(shí),Ubuntu和CentOS都是不錯(cuò)的選擇。前者更容易搜索到問題解決方案,后者的穩(wěn)定性更佳。圖1為工具鏈拓?fù)鋱D。工具鏈的各個(gè)工具搭建均可以選擇Docker容器來進(jìn)行部署,同時(shí)可以選擇一款適合自己的Docker容器可視化工具來進(jìn)行Docker鏡像和容器的管理,這樣可以避免去操作繁雜的Docker命令。Docker集群的搭建也是工具環(huán)境快速部署中必不可少的一環(huán)。
圖1 工具鏈拓?fù)鋱D
Jenkins作為搭建工具鏈實(shí)踐的核心工具,以開源免費(fèi)、跨平臺(tái)支持、分布式構(gòu)建等優(yōu)點(diǎn),在業(yè)界被很多項(xiàng)目所采用。在部署Jenkins 自己的Slave 機(jī)時(shí),使用Kubernetes 和Docker具有很好的可移植性的特點(diǎn),比起傳統(tǒng)的虛擬機(jī)方式,優(yōu)勢比較明顯。
另外需要單獨(dú)搭建的兩個(gè)重要工具為代碼管理工具和制品倉庫。代碼管理工具也有很多的選擇,其中Gerrit和Gitlab均有各自的特點(diǎn),可以根據(jù)自己團(tuán)隊(duì)的需求進(jìn)行選擇。制品倉庫工具負(fù)責(zé)對二進(jìn)制文件、制品和依賴項(xiàng)進(jìn)行存儲(chǔ)和產(chǎn)品版本發(fā)布,例如Artifactory、Nexus等開源工具。本文選擇Gerrit和Artifactory進(jìn)行工具鏈搭建。其中Gerrit負(fù)責(zé)項(xiàng)目代碼的存儲(chǔ),在穩(wěn)定性和數(shù)據(jù)備份上要足夠重視,否則一旦出問題將是重大損失。
持續(xù)集成主要工具搭建完成之后,如何設(shè)計(jì)開發(fā)集成流程和架構(gòu),書寫高效安全的執(zhí)行流程腳本,是持續(xù)集成策略設(shè)計(jì)的核心問題。
分支策略選擇根據(jù)3個(gè)約束變量,即交付時(shí)間點(diǎn)、特性數(shù)量和交付品質(zhì)分為3種版本發(fā)布的基本模式[1],分支分為開發(fā)分支、穩(wěn)定分支、發(fā)布分支,如圖2所示。其中,開發(fā)分支可以根據(jù)開發(fā)特性去創(chuàng)建不同的分支。分支創(chuàng)建及生命周期管理必須嚴(yán)格,需要及時(shí)平衡分支管理和產(chǎn)品分支策略,既不能以分支越少越容易管理來決策,也不能隨意認(rèn)為分支越多越方便開發(fā),這兩點(diǎn)都會(huì)對分支管理帶來災(zāi)難性后果。
圖2 分支策略
代碼審核階段在開發(fā)提交階段就已經(jīng)可以開始,通過Git工具的Hooks文件夾下的文件,可以在提交過程中規(guī)范提交的Commit信息和Topic信息。在Jenkins的Build構(gòu)建過程中,打分規(guī)則還可以加入靜態(tài)代碼掃描、單元測試、安全掃描和自動(dòng)化測試掃描等。代碼審核流程如圖3所示。
圖3 代碼審核流程
開發(fā)把代碼Push 到Gerrit 上 后,會(huì) 為Patch Sets 創(chuàng)建Change-ID,同時(shí)也會(huì)觸發(fā)在Jenkins上設(shè)置的Prebuild編譯功能。由于整個(gè)系統(tǒng)的編譯包含了Android和QNX等所有模塊編譯,一般情況下,服務(wù)器整編需要5~8h的編譯時(shí)間,如果把整編設(shè)置到Prebuild編譯,那么會(huì)讓開發(fā)等很久才能合入代碼。最好在Prebuild階段設(shè)置進(jìn)行模塊編譯,單模塊編譯模式需要和開發(fā)商議合理的編譯方式,編譯依賴的更新及發(fā)布是重點(diǎn),要能夠保證單模塊編譯是倉庫代碼最新的編譯。當(dāng)代碼Submit入庫之后可以進(jìn)行整編出版本,雖然有一定的整編失敗風(fēng)險(xiǎn),但是可以節(jié)約Prebuild代碼合入時(shí)間和資源。這種風(fēng)險(xiǎn)可以在設(shè)置整編版本中去進(jìn)一步解決。
版本發(fā)布是整編編譯成功后,把版本制品上傳至Artifactory上進(jìn)行Daily和Weekly版本的發(fā)布。版本發(fā)布策略如圖4所示。
圖4 版本發(fā)布策略
在Daily或者Weekly版本成功上傳后,需要集成測試人員進(jìn)行冒煙測試,然后執(zhí)行一系列的功能測試,測試通過后方能發(fā)布。其中,自動(dòng)化測試也是非常重要的一環(huán)[2]。
服務(wù)器管理和監(jiān)控工具搭建也至關(guān)重要,監(jiān)控指標(biāo)的清晰可視化可以為決策提供更加實(shí)時(shí)有效的參數(shù)。提供基于Web界面的分布式系統(tǒng)監(jiān)視工具有很多,例如Monitorix、Zabbix等監(jiān)控工具,一般涉及的重要監(jiān)控功能都能夠包含其中,例如對服務(wù)器網(wǎng)絡(luò)、性能、CPU占用、磁盤空間等參數(shù)設(shè)置及時(shí)報(bào)警通知的機(jī)制,讓系統(tǒng)管理員可以快速定位服務(wù)器問題。
集成環(huán)境一系列的工具和策略必須通過書寫腳本來實(shí)現(xiàn),腳本語言多種多樣,一般可以選擇Pipeline、Python和Shell,前兩個(gè)語言更適合面向?qū)ο笏季S,后者偏向于面向過程。Pipeline語言使用Build調(diào)度前端Job并傳參,而Shell則需要使用Curl命令進(jìn)行Job的調(diào)度。
腳本的評審和測試不能忽略,圈復(fù)雜度、注釋等靜態(tài)代碼掃描的要求也必須嚴(yán)格執(zhí)行,這些工作直接影響后期維護(hù)和功能增加的便利程度。軟件開發(fā)集成流程示例如圖5所示。
圖5 軟件開發(fā)集成流程示例
根據(jù)服務(wù)器部署的情況,一臺(tái)服務(wù)器保證每天一個(gè)產(chǎn)品車型可以出1~2個(gè)集成版本,每周至少出5個(gè)驗(yàn)證版本,取其中的穩(wěn)定版本作為周版本發(fā)布。這樣的版本迭代速度可以快速適應(yīng)功能開發(fā)的需求。
本文通過介紹持續(xù)集成工具鏈的搭建以及持續(xù)集成策略的制定等一系列的實(shí)踐,驗(yàn)證了持續(xù)集成平臺(tái)環(huán)境在汽車軟件開發(fā)過程中的參與程度越來越深化,進(jìn)而推動(dòng)汽車軟件開發(fā)效率和品質(zhì)得到進(jìn)一步的提高。