阿里在使用一種更靈活的軟件集成發佈模式

當今典型的軟件集成發佈模式是,經過相似GitHub的Pull Request或GitLab的MergeRequest的方式管理特性分支(Feature Branch):在經過代碼評審等方法確認一條特性分支上的改動沒問題後,將其合入集成用的分支。隨後,代碼改動進入在集成分支上運行的持續交付流水線,直到發佈上線。html

在阿里巴巴內部,儘管這種工做方式也獲得了研發協同工具平臺(Aone,對外叫雲效)的支持,但廣大研發同窗選擇的主流工做方式卻不是它,而是用一種被稱之爲變動(全稱變動請求,英文Change Request)的對象來管理特性分支,直到發佈。算法

初看起來,變動與Pull/MergeRequest有很多相同點,但實際它們在理念上的差異很大。微信

本文詳細介紹它們的相同點和不一樣點,並探討用戶喜歡變動這種方式的緣由,固然也會介紹相應的風險和弱點。或許閱讀本文,能給你帶來一些思考。架構

相同點

  • 變動與Pull/MergeRequest的相同點主要在於對特性分支自己的質量和流程的控制:
  • 一個變動,就像一個Pull/MergeRequest同樣,大致上對應一條特性分支。
  • 在Pull/Merge Request中,能夠看到這條特性分支上代碼改動內容,進而進行代碼評審(Code Review)。相似的,也能夠以變動爲粒度進行代碼評審。
  • 在特性分支上的代碼提交,能夠自動觸發持續集成工具作構建以及各類自動檢測,其結果能夠在Pull/Merge Request中展示。相似的,在變動中也能夠展示。
  • 能夠把Pull/MergeRequest上的最新代碼構建部署到它專屬的測試環境並運行,以進行測試和調試。在變動中也能夠這樣作。
  • 在Pull/Merge Request中能夠設定經過的條件,好比至少兩名評審者贊成,且全部的代碼評審中發現的問題都已修復或澄清,且特性分支上的持續集成流水線運行成功。在變動中也支持相似設置。

不一樣點及其主要價值

變動與Pull/MergeRequest的不一樣之處關鍵在於,這個特性分支與其餘特性分支一塊兒集成和交付的方式。函數

對於Pull/MergeRequest,隨後把特性分支合併到集成用的分支,而後就沒有而後了。哦不,是而後就再也不以特性分支爲粒度去管理了。這條特性分支已經合入集成用的分支,其上的代碼改動已經融入集成發佈的洪流之中,被裹挾着和其餘特性分支上的代碼改動一塊兒前進,去闖關經過集成-發佈的各個階段(Stage)。微服務

而變動不一樣。即使是已與其餘變動集成,它仍然具備必定的獨立性和靈活性,在確有必要時,可針對單獨變動進行操做。下面咱們經過兩個例子來詳細介紹。工具

第一個例子:簡化起見,假定集成交付過程有三個階段:平常集成測試、在預發佈環境測試、正式發佈。某應用的變動A到變動E共五個變動,在經過了平常集成測試這個階段後,進入了在預發佈環境測試這個階段。測試時,發現變動C有一個缺陷。這個缺陷由於受平常測試環境所限,在平常集成測試階段沒有暴露出來。經分析,變動C與其餘四個變動間沒有依賴關係,不會互相影響。所以,爲了讓其餘四個變動的發佈儘可能少受影響,決定把變動C從在預發佈環境測試這一階段中摘除出來。其餘四個變動在一塊兒再次測試驗證,此時該缺陷再也不出現,這四個變動在一塊兒經過了在預發佈環境測試階段,進而進入正式發佈階段,發佈上線。測試

在這個例子中,在摘除了變動C後,沒有將其餘四個變動在一塊兒再次通過平常集成測試階段,是出於兩方面考慮:一是,此時的平常集成測試環境,已經被若干新添的變動所佔用。它們的測試須要時間,並且可能也會反覆調整。把新添的變動趕出去,或者把這四個變動和新添的變動混在一塊兒,或者讓着四個變動等着,都分別有明顯的不利之處。另外一方面,A、B、D、E四個變動,它們與變動C在一塊兒,已經經過了平常集成測試。而變動C又與它們無關,所以對它們再次進行平常集成測試,發現問題的可能性很低。測試是要講究性價比的,而不是一味追求保證產品零缺陷。出於以上緣由,在具體實戰中,開發團隊就有可能根據當時實際狀況,在評估後決定,在摘除了變動C後,再也不將其餘四個變動在一塊兒送回平常集成環境,而是直接在預發佈環境再次測試。ui

第二個例子:仍假定集成交付過程有平常集成測試、在預發佈環境測試、正式發佈三個階段。某應用的變動A到變動E共五個變動,在經過了平常集成測試這個階段後,進入了在預發佈環境測試這個階段。此時,根據市場狀況變化,須要對變動C所承載的新功能作出少許調整,好比頁面說明文案上改幾個字。考慮到新的修改與變動C原有內容要麼都發布,要麼都不發佈,因此爲便於管理,新的修改就在變動C所在的特性分支上完成。這樣造成的變動C的最新內容,與其餘四個變動在一塊兒,在預發佈環境進行測試,經過後正式發佈。阿里雲

以上兩個例子,是在傳統的集成-發佈方式基礎上,加入了一些靈活性:集成-發佈過程當中,必要時能夠中途撤下變動,能夠中途修改完善變動。而有些團隊在使用變動時,採用了更進一步的方式:再也不設集成工程師之類的角色,再也不規劃統一的集成、發佈的計劃和時間點。而是每一個開發同窗負責本身的變動,不只跟蹤它直到把變動的質量提高到可集成的程度,並且由開發同窗本身把他負責的變動依次適時推入(也多是自動進入)集成-發佈的各個階段,跟蹤它直到發佈上線。也就是說,儘管進入了集成-發佈階段,各個變動還是被各自的開發者分別跟蹤和推動的:它們可能有各自的推動速率和節奏,而不會相互拖累。彼此無關的變動,只是碰巧一同使用某個測試環境,一同批量測試以提升測試效率、一同上線以免排隊而已。據此,儘量縮短了一個需求從開發到發佈上線的時間,並表現爲至關頻繁的發佈上線。同時也契合了DevOps的理念:「誰開發誰運行」(You build it, you run it)。

這一變化趨勢其實和軟件研發的管理實踐中發生的事情相似:瀑布模型時代就不提了。隨後迭代方法取代了瀑布模型。典型的,Scrum方法中的Sprint。而更進一步,在精益方法的看板牆上,迭代被弱化,關注的焦點從每一個迭代作什麼,每一個迭代進入到什麼階段,演化爲關注每一個在製品流動到了哪一個階段,以及每一個階段包含的在製品總量。

相似的,在上述變動管理方法中,從關注某個集成版本進入到集成-發佈的哪一個階段,演化爲關注每一個變動進入到集成-發佈的哪一個階段,以及每一個階段包含了哪些變動。

另外一方面的價值

以上,介紹的是使用變動管理方式帶來的靈活性,以及由於靈活務實而帶來的效率提高。變動管理方式,在信息記錄和跟蹤方面還有一些的好處:

要想方便地知道,本次測試、本次發佈,到底包含了哪些特性,只要看看包含了哪些變動就行了。變動自己有說明文字,變動還能夠關聯需求、任務、缺陷等工做項,更詳細地說明變動的目的。而在變動以外,也沒有別的代碼修改能夠經過直接提交到集成分支等途徑溜進來。

而從變動的視角,這個變動相關的全部改動,都在該特性分支上,而不會由於屢次反饋修改而散亂到各處。所以這些修改老是能夠方便地一同查看,一同操做。同時,老是可以清晰地知道這個變動的狀態,它到了哪一個階段:開發完畢了嗎?進入平常集成測試階段了嗎?已經正式發佈了嗎?等等。

變動能夠關聯需求、任務、缺陷等工做項,同時變動的狀態是能夠自動獲取的。所以,看板牆上跟蹤的工做項,從原理上就可能被自動移動,以反映其實際狀態。協做和進展,在看板牆上盡收眼底。

弱點和風險

以上談的都是這樣的變動管理方式能帶來的好處。那麼,它有沒有弱點和風險呢?

是的,它有。從大爆炸式集成到持續部署流水線,業界幾十年來幾乎一直在採用一個基本模式:老是一個集成版本,去順序經歷集成-發佈的各個階段。這樣能夠保證,下一階段收到的內容,老是精確的通過了上一個階段的檢驗。而本文介紹的變動管理方式所引入的靈活性,意味着顛覆了這一基本模式。靈活性歷來都是雙刃劍。靈活性意味着風險增長,意味着可能被濫用。

敏捷宣言認爲「個體和互動高於流程和工具」,上述變動管理方式暗合了這樣的思想。但在實際使用該方式時,須要注意到它對團隊成員提出了更高的要求:要求他們在具體場景具體案例中,可以對變動間的相關性及相應風險作出評估,並瞭解不一樣選擇對效率的影響,最終綜合作出特定場景特定案例中的決策。具體來講:

  • 變動對應的代碼改動越少,中途撤下變動帶來的風險越小。
  • 中途修改完善變動所對應的代碼改動越少,帶來的風險越小。
  • 軟件架構越好,變動中途撤下或修改完善帶來的風險越小。
  • 本次變動與其餘變動的相關性越小,中途撤下或修改完善帶來的風險越小。
  • 越緊急,越考慮靈活處理。
  • 業務角度,對軟件質量的要求越高,就越不要考慮靈活處理。

延伸一下,事實上,在微服務甚至函數服務時代,即使不使用上述變動管理方式,也有相似上文的風險,也相應須要團隊成員具有相似上文的自主判斷能力。爲何這麼說呢?

之因此把單體應用拆分爲微服務甚至函數服務,一個重要緣由就是爲了每一個服務能單獨測試和發佈上線。然而,在使用微服務甚至函數服務方式時,被測對象嚴格地講並非一個服務,而是該服務以及測試環境中與其直接或間接打交道的全部其餘服務。而當把每一個服務單獨測試和發佈時,就常常會致使本階段測試時某個其餘服務的版本,與下個階段測試時的版本不一樣,或者與未來正式發佈運行時的版本不一樣。因而就意味着相似上述變動管理方式中的風險。

相應的,這裏面就須要人來判斷(固然能夠有智能算法的輔助),本次哪些服務上的改動務必要一塊兒測試和上線,而另外幾個服務上的改動能夠單獨運做。而下次可能又是不一樣狀況,要根據下次的具體狀況判斷。

由此看來,「老是由一個集成版本,去順序經歷集成-發佈的各個階段」這個基本模式,其實已經被悄然突破了。上述變動管理方式,只是使這個突破更加明顯了而已。

落地及工具支持

以上是介紹了一種獨特的變動管理方式,介紹了優勢,也介紹了相應的風險。下面咱們來看看它在阿里是如何落地的。

首先須要一套分支方案來支持它。大致上是這樣:

  • master分支老是表明最新已發佈版本。
  • 代碼改動老是在特性分支上完成。特性分支老是從master分支上拉出的,並在必要時從master再次同步。
  • 沒有一條長期存在的集成發佈用的分支。而是集成發佈過程的各個階段,各對應一條短時間的,被自動管理的集成發佈分支。從master分支自動拉出該分支,再把各特性分支自動合併到該分支(出現衝突時人工介入),因而它上面就有了用戶想要的各特性。
  • 若是發現某個特性須要進一步修改完善,在特性分支上完成,並再次合併到相應的集成發佈分支。

在阿里,咱們如何管理代碼分支?》這篇文章對上述分支方案有更多介紹。

雲效 > 使用指南 > 持續交付 > 開發模式 > 分支模式》這篇文檔是該分支方案的詳細說明。

能夠看出,這套方案,對工具平臺的要求是比較高的:從界面角度,用戶只須要管理各個集成發佈階段分別要有哪些變動。而工具平臺要將它映射爲對集成發佈分支的管理,包括建立新分支或複用已有分支、從各特性分支到集成發佈分支的合併等等。這裏面也包括了很多算法,以儘量減小相同的合併衝突重複出現。

對工具平臺的高要求,或許是這套方法多年來一直只是在阿里巴巴內部被廣爲使用的緣由。

很多曾在阿里巴巴工做過的同窗,出去後都念叨着沒有這樣的工具支持了。不過如今好了,就像Google基於內部的Borg對外提供了Kubernetes,阿里巴巴也基於內部研發協同工具平臺Aone對外提供了雲效

雲效的公有云版和專有云版,都提供了上述方法的完整支持。不管是你對上述方法抱有興趣仍是懷有疑慮,均可以嘗試研究一下。

相關閱讀:

在阿里,咱們如何管理代碼分支

在阿里,咱們如何管理測試環境

 

原文連接 更多技術乾貨 請關注阿里云云棲社區微信號 :yunqiinsight

相關文章
相關標籤/搜索