百度APP移動研發(fā)平臺及DevOps實踐
作者丨朱煜松 郭金
來源丨百度App技術(shù)
1. 概述
百度APP從2018年開始,團(tuán)隊規(guī)模和業(yè)務(wù)規(guī)模都迎來了巨大的增長,也帶來了研發(fā)效率、組件復(fù)用、APP性能等多個目標(biāo)的挑戰(zhàn),于是驅(qū)使我們做了很多組件化的工作。隨著百度APP組件化程度的提高,組件逐步拆解到各個獨立倉庫,組件真正做到了邏輯、資源各有歸屬,主工程也實現(xiàn)了完全殼化,于是我們開始建設(shè)工具鏈(MGIT、EasyBox)來規(guī)范組件管理與使用并提升編譯速度。工具鏈更多承擔(dān)的是開發(fā)環(huán)境的配置,提升的是研發(fā)同學(xué)在開發(fā)階段的效率,但面臨整體移動研發(fā)流程瑣碎,多倉庫環(huán)境下的持續(xù)集成困難,組件質(zhì)量難以保障等問題,我們僅僅依靠工具鏈?zhǔn)遣粔虻模谑荰ekes應(yīng)運而生。

2. 百度APP移動研發(fā)平臺—Tekes
Tekes 是服務(wù)百度移動研發(fā)的一站式服務(wù)平臺,目前主要包括三個大的功能:
自動化研發(fā)流程,如自動發(fā)布、準(zhǔn)入,SDK 自動準(zhǔn)入,并在研發(fā)流程中增加約束,保障效率、復(fù)用、質(zhì)量、性能、安全等目標(biāo);
組件和APP的防控劣化,如組件復(fù)用輸出能力、整體質(zhì)量、影響用戶留存的啟動速度、體積等因素;
全局知識庫,如文檔中心、服務(wù)號、客服系統(tǒng)、考試系統(tǒng)等。
Tekes 的名稱起源于新疆的特克斯縣(Tekes County)。特克斯縣因八卦布局而聞名,是國內(nèi)唯一沒有紅綠燈的城市,城內(nèi)路路相通、街街相連,傳說從來不堵車。我們借此寓意,目標(biāo)提升超級App及孵化產(chǎn)品全流程研發(fā)效率。

目前 Tekes 管理著包括百度APP在內(nèi)的6條產(chǎn)品線,Android及iOS雙端超過800+個倉庫,1500+個組件,平均每天觸發(fā)自動化研發(fā)流程相關(guān)的流水線200+次。
接入 Tekes 后,移動端開發(fā)同學(xué)不僅可以通過自動化研發(fā)流程大幅縮短開發(fā)時間,還可以通過研發(fā)各階段流水線產(chǎn)出的質(zhì)量報告、前端頁面展示的產(chǎn)品線和組件的防控劣化數(shù)據(jù)來改進(jìn)開發(fā)流程,提升質(zhì)量意識。
Tekes 同時也貫徹了 DevOps 的理念,建立了一個全局知識庫、沉淀研發(fā)過程中的文檔,要求開發(fā)同學(xué)學(xué)習(xí)研發(fā)流程規(guī)范并通過相關(guān)考試,并且 Tekes 團(tuán)隊的同學(xué)也在持續(xù)識別和改善約束點,所有人教學(xué)相長,最終實現(xiàn)共同的目標(biāo)。
3.Tekes的架構(gòu)演進(jìn)
百度APP不同發(fā)展階段有著不同的目標(biāo),但始終對研發(fā)效率有著剛性需求,Tekes 也在不斷強化自身的架構(gòu)來支撐研發(fā)全流程高速運轉(zhuǎn),并逐步發(fā)展為現(xiàn)在的『百度移動研發(fā)的一站式服務(wù)平臺』。發(fā)展階段如下圖所示:

下面我們詳細(xì)介紹各個階段下Tekes的架構(gòu)。
丨第一階段:自動化
Tekes 一開始是作為組件二進(jìn)制自動發(fā)布準(zhǔn)入的調(diào)度后臺服務(wù),這是一套基于代碼組合入(Topic Merge)和流水線持續(xù)集成(CI)的自動化流程。
組合入是將一組(一個或多個)倉庫的代碼同時進(jìn)行合入操作。由于百度APP的客戶端代碼是多倉庫的,開發(fā)者在開發(fā)過程中不可避免地需要同時修改多個組件,此時由于代碼入庫的時機(jī)不同,導(dǎo)致入庫中間過程中持續(xù)集成觸發(fā)打包會常常發(fā)生錯誤,因此我們引入組合入的概念。
組合入基于 Gerrit 的 Topic 機(jī)制,即把一組 changes 通過同一個 topic 歸集到一起
當(dāng) Tekes 收到代碼組合入通知時,會主動觸發(fā)一條百度APP持續(xù)集成流水線,稱為『發(fā)布流水線』,這條流水線會使用 EasyBox 等工具構(gòu)建百度APP工程、編譯有代碼修改的組件并發(fā)布到組件的二進(jìn)制倉庫。整個過程稱為『發(fā)布流程』。
Tekes收到組件發(fā)布完成的通知后,會自動修改主工程的配置文件,將APP引用組件的版本自增。整個過程稱為『準(zhǔn)入流程』。
主工程,即所謂的“殼工程”,顧名思義就是客戶端工程分離業(yè)務(wù)代碼,僅僅保留一些工程配置選項和組件描述文件得到的”空殼”。構(gòu)建完整的APP工程時,會將業(yè)務(wù)代碼以組件的形式集成進(jìn)來的。
這個階段,Tekes的角色是一個調(diào)度者和連接者,本身沒有什么架構(gòu)可言。通過調(diào)度CI 流水線,連接 EasyBox 工具鏈和 百度APP,實現(xiàn)了在研發(fā)流程集成測試階段將組件從源碼形態(tài)自動發(fā)布為二進(jìn)制形態(tài),并實現(xiàn)自動化準(zhǔn)入。
組件二進(jìn)制自動發(fā)布準(zhǔn)入將每個開發(fā)人員的上車耗時從小時級別降低到分鐘級別,不僅節(jié)約了寶貴的時間,還有效地降低了版本迭代 delay 的風(fēng)險。
丨第二階段:平臺化
2019年百度APP中臺化如火如荼,隨著中臺化的工作不斷推進(jìn),不僅需要有業(yè)務(wù)中臺提供成熟的組件支持快速組裝APP,還需要技術(shù)中臺來賦能APP自動化能力,提高流程運轉(zhuǎn)效率,保障業(yè)務(wù)的連續(xù)性。
Tekes 作為技術(shù)中臺的核心能力之一,也在積極探索如何升級移動端研發(fā)模式,具體工作概括成”三板斧”。
第一板斧——自動化流程建設(shè)
完善自動化研發(fā)流程,分為橫向和縱向兩部分工作。橫向上,擴(kuò)展更多自動化流程來替代以前手動或者半手動的流水線工作,例如打包、單測、體積檢查、infer等;縱向上,在已有的流水線上增加更多的規(guī)范化約束,例如發(fā)布流程的版本號規(guī)范檢查、接口/依賴的劣化審核等,準(zhǔn)入流程的APP體積控制等。

第二板斧——移動組件管理平臺搭建
從 Tekes 獨立出了一個”移動組件管理平臺”來專門管理可復(fù)用的組件為中臺化服務(wù),完成整個組件(及SDK)發(fā)布及準(zhǔn)入的閉環(huán),如下圖所示:

移動組件管理平臺負(fù)責(zé)展示組件的數(shù)據(jù)(詳情、組件化信息及質(zhì)量報告),它的數(shù)據(jù)來源于 Tekes 的組件自動發(fā)布、組件手動發(fā)布或者 SDK/開源庫組件的手動上傳,產(chǎn)品線的中臺負(fù)責(zé)人可以通過頁面交互觸發(fā) Tekes 的組件自動準(zhǔn)入 將指定組件的指定版本準(zhǔn)入到APP中。
第三板斧——多產(chǎn)品線輸出
上游和”APP中心”(百度內(nèi)部的APP開發(fā)平臺)互通,下游和矩陣產(chǎn)品團(tuán)隊進(jìn)行接洽和工程改造。矩陣產(chǎn)品通過接入 Tekes 的自動化流程和組件防控劣化,解決其手動發(fā)布組件成本高,源碼倉庫編譯效率低,組件的質(zhì)量難以控制等問題。
這一部分屬于應(yīng)對不同產(chǎn)品線研發(fā)模式升級的實踐,本篇文章不多做介紹。
架構(gòu)
這個階段對 Tekes 進(jìn)行了平臺化的升級,明確了 Tekes 的三大服務(wù)——流程、組件和產(chǎn)品線,整個架構(gòu)如下圖所示:

分層介紹我會放在下個階段一起講。
丨第三階段:移動DevOps
2021年伊始,DevOps 作為軟件開發(fā)領(lǐng)域熱門的概念之一,并已成為敏捷軟件文化的一部分。為了更好地提升百度APP及矩陣產(chǎn)品的工程能力和研發(fā)效率,實現(xiàn)”快速交付價值,靈活響應(yīng)變化”。Tekes 也結(jié)合自身的現(xiàn)狀積極探索移動 DevOps。
DevOps 是人員、流程和技術(shù)的聯(lián)合,以不斷向客戶提供價值為目標(biāo),使以前孤立的角色(開發(fā)、IT 運營、質(zhì)量工程和安全)可以協(xié)調(diào)和協(xié)作,以生產(chǎn)更好、更可靠的產(chǎn)品。——Azure DevOps

DevOps 在不同組織的實施上天差地別,對于 Tekes 來說,移動端的自動化流程及持續(xù)集成已經(jīng)建設(shè)的相對成熟,我們進(jìn)一步實施 DevOps 的模式,首先需要整合百度移動研發(fā)流程,識別并建立價值流。
在研發(fā)流程中,價值流可以定義為從需求提出到最終轉(zhuǎn)化成產(chǎn)品,交付價值給用戶的過程。
百度的研發(fā)流程,大致可以分為需求、 開發(fā)、測試、集成和交付五個階段,我們以此建立從左到右平滑的價值流,并梳理了每個階段的主要活動,這些主要活動有些是手動的,有些是自動的(依賴我們建設(shè)好的CI/CD流水線),如下圖所示:

然后,我們做了很多可視化工作管理價值流。因為在價值流中很多問題隱藏在那些看起來習(xí)以為常的活動中,對于像百度APP這樣已經(jīng)服務(wù)了多年的產(chǎn)品,背負(fù)大量的技術(shù)債務(wù),問題隱藏的更深。可視化可以幫助識別并解決價值流中的約束點,避免問題傳遞到下一個階段。同時,還可以優(yōu)化研發(fā)同學(xué)的體驗,能夠清晰看到流水線每一個約束點執(zhí)行的狀態(tài)和產(chǎn)物等。
最后,在部門內(nèi)同步DevOps認(rèn)知和目標(biāo),發(fā)揚樂于協(xié)作積極溝通的文化,不拘泥于優(yōu)化局部指標(biāo),而是把局部經(jīng)驗轉(zhuǎn)化成全局經(jīng)驗,建立起全局知識庫。
架構(gòu)
移動 DevOps 是 Tekes 當(dāng)前所處的階段,還在不斷改善中,架構(gòu)如下圖所示:

分層介紹
Web
Tekes 平臺:移動研發(fā)平臺,面向移動研發(fā)團(tuán)隊的PMO、開發(fā)、測試、運維人員
移動組件管理平臺:管理可復(fù)用組件信息,面向產(chǎn)品線的中臺負(fù)責(zé)人
網(wǎng)關(guān):統(tǒng)一API網(wǎng)關(guān)服務(wù),反向代理、負(fù)載均衡和限流
應(yīng)用服務(wù):
DevOps服務(wù):管理全研發(fā)階段的自動化研發(fā)流程,提供可視化服務(wù)
產(chǎn)品線服務(wù):管理產(chǎn)品線數(shù)據(jù);針對具體產(chǎn)品線還有一些客制化服務(wù);
組件服務(wù):管理組件數(shù)據(jù);提供組件復(fù)用、發(fā)版和劣化防控服務(wù)。
運維監(jiān)控:業(yè)務(wù)服務(wù)的監(jiān)控(流量、請求、錯誤等),預(yù)警異常
基礎(chǔ)服務(wù):封裝的公共基礎(chǔ)服務(wù)能力,例如訪問控制、流程控制、消息通知等
上游服務(wù):依賴其他平臺提供的服務(wù),例如UUAP、iCode、iCafe、iPipe等
百度云服務(wù):容器云平臺,提供必要的基礎(chǔ)設(shè)施和中間件,例如數(shù)據(jù)庫、消息隊列、對象存儲等
全局知識庫:除了平臺功能之外,服務(wù)號、文檔中心及相關(guān)系統(tǒng),幫助提升移動研發(fā)團(tuán)隊工程能力,構(gòu)建更優(yōu)秀的APP
相較于上個階段的架構(gòu),這個階段最顯著變化是將流程服務(wù)升級成 DevOps 服務(wù)并建設(shè)了全局知識庫,具體工作我們已經(jīng)介紹過了。然而我們的工作不止于此,隨著 Tekes 平臺的壯大,越來越多的產(chǎn)品線接入到了 Tekes 中,我們一方面重構(gòu)了 Tekes 后端服務(wù)的架構(gòu),拆分微服務(wù),積極擁抱云原生來提升整體的擴(kuò)展性和穩(wěn)定性,更好地為多產(chǎn)品線服務(wù);另一方面,我們也嘗試把 Tekes 在 百度APP 的 DevOps 實踐轉(zhuǎn)化成經(jīng)驗并落地到其他產(chǎn)品線上,這是一個長期探索的過程,我們需要看的更遠(yuǎn)。
4. Tekes DevOps實現(xiàn)原理
DevOps服務(wù)是 Tekes 最核心服務(wù),具體的功能包括:
管理發(fā)布流程、提測流程等業(yè)務(wù)流程,對外提供可視化服務(wù)
觸發(fā) CI/CD 流水線,接收來自流水線的消息通知
通用的工作流服務(wù),負(fù)責(zé)流程的啟動、推進(jìn)和停止
丨業(yè)務(wù)流程

業(yè)務(wù)流程需要編排自身的流程定義,流程定義是一種描述流程圖的 DSL,我們有一套自己的流程定義的語法,解釋起來會比較麻煩,所以我們直接用流程圖代替,例如:

業(yè)務(wù)流程將流程定義注冊給工作流服務(wù),工作流服務(wù)管理了所有流程實例的生命周期,業(yè)務(wù)流程不用關(guān)心具體流程是如何執(zhí)行和調(diào)度的,只需要在監(jiān)聽方法里面寫自己的業(yè)務(wù)邏輯,實現(xiàn)了業(yè)務(wù)與流程之間的解耦。
丨CI/CD服務(wù)

CI/CD服務(wù)接收來自流水線的消息,并將其包裝成”事件”,”事件”經(jīng)過”過濾器”過濾后最終傳遞給工作流服務(wù)進(jìn)行處理。
事件
流水線通過事件和工作流服務(wù)建立聯(lián)系。事件有三種類型,都直接或間接來自于流水線的通知,如下圖:



基礎(chǔ)事件,來自于特定流水線請求
變更事件(Change Event)。倉庫代碼change合入前流水線(Change流水線)的消息,包含一些基本的變更信息;
合入事件(Merge Event)。倉庫代碼change合入后流水線的消息,除了一些基本的變更信息外,還有評審人合入人的信息;
基礎(chǔ)擴(kuò)展事件,目前的擴(kuò)展事件都是經(jīng)過合入事件特殊處理而來的。各個基礎(chǔ)擴(kuò)展事件彼此獨立,但是和合入事件并存
新提交事件(NewCommit Event)。來自倉庫拉出新分支第一次提交的消息。因為這種提交會跳過評審直接合入,所以單獨處理;
組合入事件(TopicMerge Event)。同一個topic下的倉庫change全部合入后的消息,包含一個或多個合入事件。組合入事件是啟動 提測/發(fā)布 流程的事件源;
Tekes合入事件(TekesMerge Event)。Tekes自動流程生成的change(通常是自動準(zhǔn)入)合入后的消息。因為這種提交會觸發(fā)Tekes的自動評審和合入,所以也單獨處理。
自定義事件,這是最多的事件,當(dāng)CI流水線執(zhí)行一個業(yè)務(wù)流程時,完成每一項任務(wù)(例如組件化檢查)都會請求一次Tekes,會生成對應(yīng)的事件,可以說自定義事件是推進(jìn)流程的事件源。
過濾器
CI/CD服務(wù)處理事件時會有若干個過濾器,這里的過濾器基于責(zé)任鏈模式串聯(lián)起來,形成一條過濾鏈。事件在鏈上傳遞,每一個過濾器都有機(jī)會處理該事件,并在處理后選擇攔截或繼續(xù)傳遞。
責(zé)任鏈模式在面向?qū)ο蟪淌皆O(shè)計里是一種軟件設(shè)計模式,它包含了一些命令對象和一系列的處理對象。每一個處理對象決定它能處理哪些命令對象,它也知道如何將它不能處理的命令對象傳遞給該鏈中的下一個處理對象。該模式還描述了往該處理鏈的末尾添加新的處理對象的方法。
我們介紹事件時說到 組合入事件是啟動 提測/發(fā)布 流程的事件源,我們就以他為例,介紹一下他連接的過濾器:

TekesIgnoreFilter: 判斷 Tekes 是否處理這個事件,例如 Tekes關(guān)閉了自身 DevOps服務(wù) 或者 此次提交的change信息命中了 Ignore 的邏輯(例如倉庫、提交人,commit log關(guān)鍵字);
TopicMergeValidator:校驗組合入是否有效,因為獲取組合入的信息需要依賴上游服務(wù)(iCode),我們會在這里重新請求一次確保當(dāng)前topic下的所有提交都已合入并能和 TopicMerge Event 包含的所有Merge Event一一對應(yīng);
MatchAppJudge: 裁決 TopicMerge 匹配的產(chǎn)品線(實際上是產(chǎn)品線的主工程),如果裁決不出來則返回失敗。因為 TopicMerge 只有一組倉庫合入的信息,沒有產(chǎn)品線的信息,而后續(xù)如果觸發(fā)流程,需要基于一個產(chǎn)品線的主工程去構(gòu)建、編譯及打包。由于存在多個產(chǎn)品線復(fù)用組件(倉庫)的情況,我們裁決產(chǎn)品線有一套比較復(fù)雜的判斷邏輯,這里也不做詳細(xì)介紹。
使用過濾器處理事件有幾個好處:
解耦。請求者(流水線)將事件傳遞給責(zé)任鏈后,不用關(guān)心具體的處理者;
靈活。允許動態(tài)地組合過濾器,形成新的責(zé)任鏈實現(xiàn)不同的功能;
優(yōu)雅。每個過濾器只負(fù)責(zé)處理自己的部分,符合開閉原則。
丨工作流服務(wù)

在介紹工作流服務(wù)前,我們先介紹”工作流”,根據(jù)維基百科定義:
工作流(Workflow),是對工作流程及其各操作步驟之間業(yè)務(wù)規(guī)則的抽象、概括描述。工作流建模,即將工作流程中的工作如何前后組織在一起的邏輯和規(guī)則,在計算機(jī)中以恰當(dāng)?shù)哪P捅磉_(dá)并對其實施計算。工作流要解決的主要問題是:為實現(xiàn)某個業(yè)務(wù)目標(biāo),利用計算機(jī)在多個參與者之間按某種預(yù)定規(guī)則自動傳遞文檔、信息或者任務(wù)。
工作流引擎是驅(qū)動工作流的工程實現(xiàn),負(fù)責(zé)解釋流程定義、管理流程數(shù)據(jù)、控制流程運行,并和業(yè)務(wù)解耦。我們的工作流服務(wù)就是對工作流引擎的封裝。
工作流服務(wù)有四個模塊:
流程控制服務(wù)適配器。流程控制服務(wù)(工作流引擎)的適配器,封裝了流程部署、流程啟動、流程停止及流程推進(jìn)等多個接口的調(diào)用。適配器的好處是方便替換依賴的工作流引擎;
流程執(zhí)行器。事件最后的處理器,通過解析事件獲取參數(shù),進(jìn)一步調(diào)用適配器啟動流程或推進(jìn)流程的方法;
流程注冊中心。注冊業(yè)務(wù)流程的流程定義和資源,流程注冊會進(jìn)一步調(diào)用適配器流程部署的方法,資源注冊則會將業(yè)務(wù)流程的回調(diào)方法保存到注冊表中;
流程調(diào)度器。監(jiān)聽運行中的流程,會根據(jù)注冊表的信息,將對應(yīng)流程或階段的回調(diào)消息分發(fā)給業(yè)務(wù)流程
我們用一張圖展示一下這四個模塊以及”流程控制服務(wù)”之間的調(diào)用關(guān)系:

5. 結(jié)語
無論是移動研發(fā)效能提升還是DevOps實踐,都沒有銀彈。不同的企業(yè)之間、部門之間和產(chǎn)品之間都存在著差異,很難有一個通用的平臺或工具去適配所有場景、解決所有問題。
而 Tekes 做的,就是從百度APP出發(fā),在不同階段不同目標(biāo)下,做到最好的提升移動研發(fā)效能的解決方案。通過建設(shè)平臺和開發(fā)工作流,制定規(guī)范和輸出文化,讓百度移動研發(fā)團(tuán)隊的移動開發(fā)同學(xué)能夠?qū)W⒂诮桓秲r值,最終我們也能成為整個百度APP移動研發(fā)價值的一部分。
參考鏈接
1. MGit開源地址
https://github.com/baidu/m-git
2. 百度App iOS工程化實踐: EasyBox破冰之旅
https://mp.weixin.qq.com/s/Oa52PvsHw8wS-OvYb3ArZg
3. 百度App組件化之路
https://mp.weixin.qq.com/s/P-vREnrw4xGyhiugpzB-1Q
4. gerrit set-topic
https://gerrit-review.googlesource.com/Documentation/cmd-set-topic.html
5. Azure DevOps:什么是 DevOps
https://docs.microsoft.com/zh-cn/devops/what-is-devops
6. DevOps
https://zh.wikipedia.org/wiki/DevOps
7. 責(zé)任鏈模式
https://zh.wikipedia.org/zhhans/%E8%B4%A3%E4%BB%BB%E9%93%BE%E6%A8%A1%E5%BC%8F
8. 工作流技術(shù)
https://zh.wikipedia.org/wiki/%E5%B7%A5%E4%BD%9C%E6%B5%81%E6%8A%80%E6%9C%AF
9. 工作流參考模型
https://zh.wikipedia.org/wiki/%E5%B7%A5%E4%BD%9C%E6%B5%81%E5%8F%82%E8%80%83%E6%A8%A1%E5%9E%8B
-End-
最近有一些小伙伴,讓我?guī)兔φ乙恍?nbsp;面試題 資料,于是我翻遍了收藏的 5T 資料后,匯總整理出來,可以說是程序員面試必備!所有資料都整理到網(wǎng)盤了,歡迎下載!

面試題】即可獲取
