1. 程式人生 > 其它 >3個案例,詳解如何選擇合適的研發模式 | 研發效能提升36計

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

 

策劃&編輯|雅純

上一講,我們詳細介紹了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