前段時期我負責部門內部主干開發落地相關事宜,這個程序中,也真真切切的體會到了多人開發程序中,面對特性分支管理中,大家遇到的一些困擾,尤其面對敏捷迭代的開發方式,合并沖突,集成測驗,代碼重用等方面,都與高效兩個字背離,當然,我在推進主干開發程序中,也遇到了一些問題和坎坷,在這里,集中的做一次分享,
1. 概述
主干開發,是指開發人員直接向主干(習慣上主干分支通常為:trunk 或 master)提交 / 推送代碼,通常,開發團隊的成員 1 天至少 1 次地將代碼提交到主干分支,在到達發布條件時,從主干拉出發布分支(通常為 release),用于發布,若發現缺陷,直接在主干上修復,并根據需要 cherry pick 到對應版本的發布分支,
優點:
-
分支模型簡單高效,開發人員易于掌握不容易出現錯誤操作
-
避免了分支合并、沖突解決的困擾
-
隨時擁有可發布的版本
-
有利于持續集成和持續交付
缺點:
-
基礎架構要求高:合入到主干的代碼若質量不過關將直接阻塞整個團隊的開發作業,因此需要高效的持續集成平臺進行把關;
-
自動化測驗要求高:需有完備單元測驗代碼,確保在代碼合入主干前能在獲得快速和可靠的質量反饋;
-
最好有代碼評審:若代碼質量要求高,需要配套代碼評審(CR)機制,在代碼提交到主干時,觸發 CR,通過 Peer Review 后才能正式合入;
-
最好有特性開關:主干開發頻發合入主干的情況下,特性拆分得很小,可能是半成品特性,需要配套特性開關(Feature Toggle),只有當特性整體開發完才通過灰度發布等手段逐步打開;
適用環境:
-
對迭代速度要求高,希望需求快速交付上線
-
基礎架構強,持續集成工具高效;
-
團隊成員習慣 TDD(測驗驅動開發),代碼自動化測驗覆寫率高(至少增量代碼的自動化測驗覆寫率高);
2. 整體架構
2.1 衡量主干開發的效果
可以通過執行以下操作來衡量主干開發的效果,
| 測驗的因素 | 衡量的指標 | 目標 |
|---|---|---|
| 應用代碼庫中的活躍分支數, | 衡量應用代碼庫版本控制系統中的活躍分支數,讓所有團隊都能看到此數字,然后跟蹤目標狀態的增量式進度, | 不超過三個活躍分支, |
| 代碼凍結期, | 衡量團隊的代碼凍結數及凍結時長,這些衡量指標還可以對合并沖突、代碼凍結、穩定等方面所耗費的時間進行分類, | 無人提交代碼時,沒有代碼會被凍結, |
| 將分支合并到主干的頻率, | 衡量合并的每個分支的二進制(是/否)值,或者衡量每天合并的分支的百分比, | 每天至少合并一次, |
| 查看審批代碼更改所需的時間, | 如果您異步執行代碼審核,請衡量審批更改請求所需的平均時間,并特別關注所需時間大大超過平均值的請求, | 設法使代碼審核成為在開發程序中執行的同步活動, |
2.2 常見誤區
如需全面采用主干開發,需要避免以下常見障礙:
-
繁瑣的代碼審核流程,許多組織的代碼審核流程都較為繁瑣,需要多次審批才能將更改合并到主干中,如果代碼審核很費力并且需要數小時或數天才能完成,開發者會避免小批量作業,改為進行大批量更改,因為大批量代碼審核十分復雜,因此審核人員的審核時間會延長,進而造成惡性回圈,
-
這樣的結果是開發者避免使用合并請求,從而導致合并請求經常受到冷落,由于很難通過檢查來推導大規模更改對系統的影響,因此審核人員很可能會忽略缺陷,主干開發的優勢也就減弱了,
-
異步執行代碼審核,如果您的團隊實行結對編程,那么該代碼已由第二個人審核,如果需要進一步審核,則應該同步執行:開發者準備提交代碼時,應立即讓團隊中的其他人員審核代碼,開發者不應該要求進行異步審核,例如向工具提交請求,然后在等待審核時啟動新任務,合并延遲時間越長,就越有可能發生合并沖突和相關問題,如果執行同步審核,需要團隊同意優先審核彼此的代碼而不是處理其他作業,
-
在提交代碼之前未運行單元測驗或者自動化測驗,為了確保主干保持作業狀態,在提交前對代碼更改運行測驗非常重要,此操作可以在開發者作業站完成,許多工具也提供針對本地更改遠程運行測驗,然后在通過測驗后自動提交更改的功能,如果開發者知道自己無需大量繁雜流程即可將代碼提交到主干,那么就會小批量更改代碼,這些更改易于理解、審核、測驗,并且可以更快地遷移到生產環境,
2.3 改進主干開發的Tip
-
小批量開發,主干開發最重要的推動因素之一就是團隊學習如何小批量開發,這需要為開發團隊提供培訓和組織支持,
-
執行同步代碼審核,如前所述,轉換為同步代碼審核或至少確保開發者優先進行代碼審核,有助于確保所做的更改不必等待數小時甚至數天即可合并到主干中,
-
執行全面的單元測驗和自動化測驗,確保您擁有全面而實用的自動化單元測驗套件,并在每次提交之前運行這些測驗工具,
-
快速構建,構建和測驗程序應在幾分鐘內執行,目標是將測驗環境的jdos部署串聯到整個CI的自動化流水線之中
2.4 主干開發流程說明
如圖所示,研發小伙伴基于master分支開發,當每次merge時,都會觸發流水線驗證程序,在流水線驗證中:
1.EOS代碼掃描,該掃描會掃描代碼中不規范的情況,按照代碼規約不同,會有不同的級別,包括 WARNING, MAJOR, CRITICAL, BLOCKER四種級別,基于不同級別可以設定攔截規則,如果代碼不符合設定的攔截規則,將不予merge,
2.代碼評審會觸發代碼評審邀請,可以根據設定,邀請組內研發,leader,或者測驗人員參與代碼評審,通過設定規則,如果代碼評審通過,才允許merge,
3.現在自動進行maven打包和單元測驗作業,如果單元測驗不通過,將不予merge,
4.流水線會自動將單元測驗通過的jar包發布到測驗的JOS分組進行部署,部署完成后自動調取線上自動化測驗流程,只有所有介面通過自動化測驗,才允許merge,
3. 落地方案
3.1 單元測驗
應用架構: 基于spring boot junit 撰寫單元測驗,
我們可以將測驗按照模塊劃分,放在不同的目錄之下,可以分為集成測驗和單元測驗,這樣做的原因是,當我們的專案邊的越來越大的時候,寫的測驗會越來越多,當所有測驗都放在一個目錄下的時候,跑一次集成測驗時間會很長,具體目錄如下:
| 主開發目錄 | 測驗開發目錄 | 測驗模塊 | 描述 | 測驗父類命名 |
|---|---|---|---|---|
| src/ | test/ | init | 初始化測驗模塊 | InitTestBase |
| unit | service單元測驗模塊 | UnitTestBase | ||
| jpa | 持久化層測驗模塊 | JPATestBase | ||
| mvc | controller層測驗 | MvcTestBase |
所有測驗模塊集成對應的父類,然后類名必須以對應模塊+Test結尾,例如:ShipperStatisticUnitTest
- 引入單元測驗依賴 spring-boot-starter-test
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2. 引入 surefile 插件
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<skip>false</skip>
<includes>
<include>**/unit/*Test.java</include>
</includes>
</configuration>
</plugin>
3. 配置測驗組態檔路徑
<resources>
<testResources>
<testResource>
<directory>src/test/resources</directory>
<!--①-->
<excludes>
<exclude>application*.properties</exclude>
</excludes>
</testResource>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
<includes>
<include>application.properties</include>
<include>important.properties</include>
<include>application-${activatedProperties}.properties</include>
</includes>
</testResource>
</testResources>
3.2 JaCoCo代碼覆寫率掃描
該處可以先串聯到流水線中,但不做門禁設定,等后期確定標準后,再打開門禁設定,
3.3 EOS靜態代碼掃描
在主干開發模式中,因為EOS靜態代碼掃描,配置代碼合并門禁,確保代碼編碼規范,配置如下圖所示例子:
3.4 代碼線上評審
代碼評審通過Coding內置的評審規則實作,規則設定如下:
1.評審分支為master分支,并在push時創建代碼評審,并阻塞代碼直接合入目標分支,
2.評審人需要達到兩人及以上通過后,才能觸發隨后的操作,
3.不允許自評,
4.不允許特定成員跳過自動化檢查,
3.5 特性開關
遇到此情況,一般是多版本同時開發的情況
此處跟業務強相關,需要具體問題具體分析,不過保證如下幾個原則:
-
代碼開發盡量保證高內聚低耦合,保證類的封閉性,同時可以用常用設計模式,保證功能的業務代碼解耦,有利于特性區分,
-
個別情況,可以引入ducc配置中心,實作特性開關,
3.6 流水線配置
在行云流水線中,主要包括如下幾個節點:
其中有一個配置上有一個小坑就是下載代碼,為什么這么說呢?
因為我們流水線的觸發條件是跟coding上的代碼評審配合使用,當主干分支發生merge請求時,這個時候會觸發流水線,但拉取的代碼并不能直接填寫主干分支名稱(如:master), 原因是當前的commit快照并沒有合并到master上,而是處于等待狀態,只有當流水線通過后才會真正合并到主干分支,這是如果下載代碼里拉取的主干分支就是不包含當前提交內容的快照,并不能滿足我們的訴求,
那么,我們該如何配置呢?
好在Webhook中會帶一些系統內置全域引數,其中globalParams.user.WEBHOOK_ATTR_COMMIT_ID,代表的就是當前提交請求所包含的 commit快照,所以,我們只需要配置這個全域引數即可,如圖所示:

配合如上配置,我們在觸發設定中,只需要設定MR created/Updated事件即可,如下圖所示:
4. 總結
于許多開發者而言,主干開發是一項重大變革,您很可能會遇到一些阻礙,許多開發者根本無法想像如何采用這種方式作業,一項好的做法是找到曾采用這種方式作業的開發者,讓他們指導其他開發者,讓一些團隊轉為采用主干開發方式作業也很重要,實作此目標的一種方法是將大量具有主干開發經驗的開發者召集到一起,這樣至少有一個團隊遵循主干開發做法,然后,如果您確信遵循此做法的團隊發揮預期的作用,則可以將其他團隊轉換為這種風格,
當然主干開發也不是銀彈,他也會有一些自己的弊端,比如在處理需求變更,或者同時多版本并行開發時,也需要建立多個臨時分支支持,想做到純粹的主干開發,也是過于理想化的結果,
作者:京東物流 趙勇萍
來源:京東云開發者社區
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/554618.html
標籤:架構設計
上一篇:【618備戰巡禮】“三高”之第一高--如何打造高可用系統
下一篇:返回列表
