天天看點

3個案例,詳解如何選擇合适的研發模式 | 研發效能提升36計

摘要:3個案例,詳解如何選擇合适的研發模式,研發模式的選擇與産品形态、釋出方式、團隊規模、協作成熟度密切相關。本文我們将根據不同的團隊場景,分析如何選擇适合自己團隊的研發模式。

策劃&編輯|雅純

上一講,我們詳細介紹了4種常見的分支模式及其優劣對比。本文我們将根據不同的團隊場景,分析如何選擇适合團隊的研發模式。

研發模式選擇看什麼

研發模式的選擇與産品形态、釋出方式、團隊規模、協作成熟度密切相關。比如團隊規模很小,協作成熟度很高,就直接用主幹開發。類似于Web服務端的開發,可以做到持續部署,可以選擇GitHub—Flow,或者是TBD。

如果你的團隊規模比較大,需要開發的時候做相應的隔離,再看協作的成熟度。如果一般就用GitHub—Flow,成熟度很高就用TBD。

另外,有一些研發場景有固定的釋出視窗,它是按版本的方式去釋出,我們建議有相應的release分支去做隔離。實際過程中我們應該盡可能地根據自己實際的産品和團隊情況,來去制定合适的分支規則。

舉一個例子,這張圖的上半部分是需求價值流。可以看到他們開發的時候是一個需求一個需求地做,做完一個需求再做另外一個。是以可以看出這是一種持續傳遞需求的方式,針對一個需求會做相應的代碼變更。

與之相應的分支模式為GitHub—Flow。

在做特性開發的時候,隻要做特性之間的隔離,但是可以做到持續釋出,是以直接在Master上釋出就好,因為是在Master上去釋出,是以不會同時有兩個釋出存在。

可以看到分支模式和釋出流水線之間是強相關的。釋出流水線會基于不同的分支來去做相應地事情。比如特性分支發生變化後,針對特性分支做相應的內建和驗證,通過後再合到Master上去做內建,完成內建後做相應的SIT(系統級别的驗證),然後再做部署。是以分支模式和釋出流水線之間是強相關的。

這是持續釋出的方式。

版本制釋出模式常見于用戶端的釋出。例如iOS或安卓,因為有一定的釋出節奏。和上面的持續釋出模式相比多了一個release分支,用來做版本釋出用。從整體來看分支模式比較簡單。不建議用Git—Flow,可以對其适當進行裁剪。

研發模式的目的是減少代碼協作當中的沖突,減少等待。代碼之間的協作沖突有兩種,一是開發過程中的沖突和隔離,另一個是釋出過程中的隔離,是以組合方式無非是:分支開發和主幹釋出、分支開發和分支釋出、或是主幹開發和分支釋出等幾種。

這個例子初看和Git—Flow一樣,但是相對于Git—Flow,它有兩個變化。首先,它沒有release分支,它的釋出表現為在主幹上打Tag。第二,它的hotfix不合回主幹,而是直接在hotfix上打Tag進行釋出。這樣它就少了release分支,少了hotfix和master之間的同步。

整個分支模式有這樣一個特點,它有四種分支:feature分支、develop分支、master分支和hotfix分支,其中develop和master是長期分支,feature和hotfix是短期分支。開始開發的時候會拉一個feature分支,合并完成後消亡掉,如果是熱修複,會拉一個hotfix分支,hotfix分支永遠是從tag上建立的,之後建立tag,分支消亡。

是以長期分支就兩個,大部分的情況下hotfix就是feature分支,整個流程比Git—flow簡化很多。

分支模式實踐案例分析

分支模式是和産品的形态和團隊是強相關的,以下是幾個實踐案例。

1、P2P直播CDN産品

第一個案例是P2P直播CDN産品,左邊是它的架構圖,分為一個用戶端和一個服務端。用戶端是有多端的,比如手機、路由器、機頂盒等,每一種端的釋出形式是不一樣的。終端,用戶端和服務端之間有兩條通信鍊路,一條是視訊資料的鍊路,另外一條是控制資料的鍊路。

服務端包括了三部分,控制面、使用者面,和資料、營運、監控等服務。每一塊都包含多個具體的應用。團隊成員實體上在一起,協作緊密,工程能力還可以,有單元測試和功能自動化保證,基本上可以做到比較快的測試回報。

它有兩種應用:一個是服務端應用。一般golang、C++都是通過源碼級建構依賴,運作時依賴配置中心,共30個左右應用,一次釋出一個應用,每個應用是獨立釋出,是以不存在釋出的依賴性和編排問題。

另外一個是用戶端,一個代碼多端建構,無運作依賴,有的可以熱更新,有的需要通過應用市場釋出,比如說iOS,是以釋出頻率不太一樣,會導緻長期有多個版本存在。那麼,怎樣針對服務端和用戶端去做研發模式的設計?

首先看服務端,服務端是一個看上去比TBD還簡單的模式,因為人很少,服務拆得足夠小,幾乎每個服務同時隻有1—2個人在修改。這樣的情況下就沒必要再用release分支,直接在主幹上開發。基本上一個服務一個庫,而且這個服務拆得粒度很小,平均一個人大概是3、4個應用,這個服務是很小的。

這樣的情況下,它會有一些自己的紀律,比如因為要保證多端和用戶端多版本,代碼需要保證向前相容,同時代碼是直接Push在Master分支上的,不存在合并等問題。在Master上一旦代碼送出會有對應的測試,如果測試失敗,送出者需要在一小時内修複。在Master上建立Tag即會視為一次釋出。

如果出現問題,在最新代碼上修複,永遠釋出最新的版本。這就是服務端的流水線,是以如果有類似的團隊建議可以嘗試一下,基本上來說如果做好紀律,可以做到很高效地釋出。

用戶端基本上就是TBD的模式。平時還是主幹開發,代碼在主幹上內建,但是要釋出的時候會拉一個release分支,因為用戶端的釋出和更新比較困難,需要做足夠多的釋出前驗證,這個情況下就需要release分支去保護。同時因為它會同時存在多個版本,是以需要在release分支上做bugfix。

但是,release分支還是要保持活躍數盡量地少,是以一般隻關注最新的活躍的release分支。這樣TBD是一個非常合适的模式,針對釋出它會做隔離,另外,因為一個版本需要保持一定時間的維護,是以需要一個相對長期的release分支。

2、基礎網絡産品

它是在軟體層面做的虛拟化網絡産品,很多外部做一些底層産品的公司會遇到這樣類似的産品。整個産品研發50人左右,分為5個團隊,每個團隊大概10個人。團隊間協作需求很高,一般都是一起釋出、一起內建,但開發的時候是很多人一起開發的。

整個團隊工程能力中等,有單元測試但是沒有其他測試的保護,後面的測試主要是靠具體的環境去測,開發的語言是C+和C++為主,部署到實體機或者虛拟機上。應用是一份代碼,多端建構,需要應對多種的硬體和作業系統,底層依賴Hypervisor和硬體。部署時可能需要停機,因為網絡問題不是總能做到熱更新,一次部署一個應用,釋出順序有要求。

如果有多個應用,應用間的釋出有編排順序,它的釋出周期很長,通常幾個月釋出一次,同時會存在兩個都在釋出的版本,比如一個版本釋出了80%,另外一個版本釋出了10%。

這個産品的release分支會更長,它的版本需要固定下來,要有明确的Tag。是以Master不能直接送出,永遠指向最後一個已釋出的版本,但是整個開發其實是拉release去做,這個release可能會比較久。

在這邊做完以後,在release做完整的測試和評審然後釋出,完成後合進Master。這個類似于項目制,一個release相當于一個項目,從Master上建立出來以後,所有的開發和釋出的工作都在這個release分支上,這個release分支就相當于項目的版本。釋出完後release分支進入維護階段。Master在這裡是作為一個穩定基線來管理的。

3、金融安全産品

這個産品一份代碼提供兩種傳遞形态,包括SaaS和私有化傳遞形态。整個應用架構比較簡單,包含一些背景服務和API入口,以及一個管理和配置用的控制台。背景服務裡面API會調很多其他的服務,比如裝置指紋、名額計算、資料服務等。

這是典型的大資料場景,包括很多人工智能的産品都是類似的架構。整個團隊在150人左右,它的特點是前端、算法、後端、測試都有專門的職能團隊,但是沒有運維。

團隊之間通常需要協作才能完成一個要求,一般來說不會有一個需求落在某一個團隊,工程能力一般,沒有單元測試和自動化功能測試的守護,基本上是靠後續的人工測試來去保證品質。

整個技術棧是以Java為主,K8s部署方式。另一個特點是二方包依賴較多,snapshot和release版本都有。運作時應用間有較強依賴,比如在API依賴了裝置指紋,API依賴了名額計算,類似這樣的依賴其實很多。

整個應用數大概是20個,一個應用很多人協作,一次釋出往往是一組應用或者是一個應用,SaaS版本落後私有化版本較多。

它和Git—Flow有點類似,差別是沒有Develop分支,release分支用來做了臨時的內建分支,Master是釋出分支,永遠指向最新可釋出版本。

作為私有化産品,有固定的版本節奏,一般一個月釋出一個版本,于是每個月會拉一個release分支來做這個月的Feature分支的內建。內建完以後會合回Master去做釋出,釋出完打一個Tag。

是以在這裡的release分支相當于一個疊代分支。整個測試是比較長的周期,同時也要維護多個版本,是以會有多個并行的release分支存在。

通過這幾個例子可以發現,我們需要根據團隊和産品的特征來确定它的分支模式。在這些分支模式裡面,我們都盡可能地減少分支,讓分支的維護成本低一點,因為每多一個分支意味着多一份維護成本。

除此以外,還有一些其他的場景,比如內建過程中,內建進去以後發現內建分支出現問題,需要把相應地代碼摘出來。很多的Feature分支合在一起,合并進去以後想再摘出來就很難。這種情況其實也可以用分支,比如臨時的內建分支解決。阿裡内部的研發工具Aone,有一個分支模式叫Aoneflow,就可以解決相應的問題。

很多時候分支是可以很靈活地去使用的,但是靈活使用也會給程式員帶來特别多了解和維護成本。我們的建議是分支越簡單越好,另外盡可能地減少程式員的關注度,隻關注在自己開發的分支上就好。這裡給出幾點建議:

  • 單主幹:一個代碼倉庫應該保證有且僅有一個主幹分支。像Gitflow裡面Develop和Master就比較迷惑。
  • 最少長期分支:避免沖突的前提下,盡量減少長期分支的數量
  • Promotion(晉級):代碼的送出應該是逐級合并,如Feature–Develop-Master,是逐漸地Promotion的過程。
  • 釋出不可變:釋出的版本是不可變且可回溯的,可以根據Commit來追溯到你最早的源頭。
  • 自動化事件觸發:分支的持續內建過程應該是自動化的,且通過代碼送出事件或制品變更事件自動觸發。

總結

  • 團隊研發本質上是一個異步的、延遲協作的過程,随着産品複雜度和團隊複雜度的增加,協作成本快速上升。
  • 研發模式的本質是為高效傳遞需求,研發團隊圍繞代碼庫的一系列行為限制。
  • 通過分支進行隔離,避免沖突;通過小批量頻繁送出,減少等待。
  • 控制分支需要考慮最大化生産力及最小化風險。
  • 分支的選擇需要綜合團隊規模、協作成熟度、産品傳遞形态幾個要素。

下一講,我們将進入可信釋出篇,敬請期待。

點選下方連結,免費體驗雲效流水線Flow。

https://www.aliyun.com/product/yunxiao/flow?channel=yy_rccb_36

關于我們

了解更多關于雲效DevOps的最新動态,可微信搜尋并關注【雲效】公衆号;

福利:公衆号背景回複【研發效能】,可獲得精品課程【阿裡巴巴研發效能提升36計】

ps:本課程将從研發效能的定義和度量着手,逐漸深入解析來自不同業務部門提升持續傳遞能力的實踐、方法和工具,同時還将分享如何基于持續傳遞能力,切實提升産品和業務創新的效率和效果。

看完覺得對您有所幫助别忘記點贊、收藏和關注呦;

繼續閱讀