持續交付與傳統敏捷的矛盾

玄學醬發表於2017-07-10

我在採用持續交付的組織中和開發團隊工作一起工作,發現很多開發者認為的正確的敏捷團隊的工作方式,在這裡跑得不是很順暢。我認為傳統敏捷與持續交付的矛盾的根本在於,二者是採用不同的方式把軟體變得“可以釋出“(ready to release)的。

  軟體交付的演進

  使軟體變得可以釋出的過程一直在不停進化,下面是一個簡要的介紹:

  瀑布模型

  瀑布模型認為,當一個軟體所有的功能都發開完畢的時候(也就是功能完整的時候),才可以釋出。

  敏捷:

  敏捷引入的思想是,在整個開發過程中,軟體都應該“可以釋出”。許多敏捷的版本(在這篇文章裡被稱為傳統敏捷)都認為,“可以釋出”應該在固定週期的間隔點上完成。

  持續交付:

  持續交付是敏捷的一個子集,在持續交付中團隊會保持軟體在開發過程的所有時間內都可以釋出。它和傳統敏捷不同之處在於,持續交付在開發過程中不會有停下來然後建立釋出版本的過程。

  持續性交付不是指更短的週期

  從傳統的敏捷開發流程變成可持續性交付,不是指把軟體釋出的週期變短。每天晚上做釋出版本仍然不是可持續性交付。可持續性交付是說要把”做可以釋出的軟體”這個動作本身從開發過程中去掉,取而代之的是保持軟體在開發的過程中始終是可以釋出的。

  可以釋出不是意味著真正的釋出

  有一個普遍的誤解是可持續性交付就是非常頻繁地釋出出產品。而當一些組織把每天數次釋出軟體當作是持續交付的標杆時,就更加深了這一誤解。可持續性交付不是一定要頻繁的釋出,它只是要求在開發過程中的任何一個點上,用非常少的工作,軟體就能夠釋出(可參考Jez Humble的文章,可持續性交付VS可持續性部署)。儘管具備這一能力為更加頻繁的釋出敞開了大門,但是許多團隊還是從持續交付的實踐中,找到了壓倒性的證據,來證明即便釋出不是很頻繁時,持續交付也是有用的。

  持續交付和傳統敏捷的衝突點

  我前面講過,有時候持續交付和開發團隊所認為是“正確”的敏捷實踐流程有一些矛盾。

  衝突點:當有工作沒有完成時,軟體依然是可釋出的

  其中一個衝突點是,一個迭代結束時,程式碼庫中是否可以包含未完成的使用者故事(user stories)或者bug修復。我在上一篇關於迭代的帖子中做了探討。這個問題主要是源於,傳統敏捷認為在迭代結束時,team停止開發,並且來做準備軟體釋出的一些額外工作,但是,如果團隊採用持續交付,讓軟體可釋出就沒什麼額外的工作需要做。

  更有甚者,持續交付團隊甚至認為,通過使用功能切換等技術,他們的程式碼即使在還有功能沒有完成也可以釋出成產品。這也從另外一個方面說明,團隊在迭代結束時能夠達到可以釋出的要求,即使有未完成的使用者故事。

  這可能稍微有點難理解,團隊肯定還是可以要求在迭代結束點上所有的工作都必須完成,但是這容易讓人感覺是團隊原有的正常開發的節奏被隨便打斷了。持續交付不是要求沒有時間盒的迭代,這兩種實踐其實是互補的。

  衝突點:snapshot(軟體快照)/釋出版本(release build)

  許多開發團隊把軟體的版本分為“snapshot”版本和“release”版本。這個並不是敏捷所特有的,而是隨著Maven的興起,被深深植入了Java開發中,因為Maven把snapshot的概念放入了它的設計核心中。這種方案把開發週期劃分成兩個階段,在軟體開發過程中使用snapshot,當軟體成為可以釋出狀態時才建立release版本。

  很明顯,這種釋出週期的劃分和持續交付的“軟體應該總是可以釋出”的理念是相沖突的。持續交付通常採用的方式是隻在開始建立一次版本,然後通過不同階段的測試驗證等一系列序列工作來對版本進行改進,如果使用Maven,要用兩種方式建立版本,這種方式就不行了。

  其實完全可以使用Maven做持續交付,比如說,為每個版本建立一個release build。當然,這個會和Maven的“release build只以生產部署為目的,不會經常建立”的理念矛盾。而且,像Nexus和Artefactory這樣的私服都有刪除舊的snapshot版本的清理功能,但不允許刪除release版本。所以一個活躍的持續交付團隊,一天可以產生幾十個版本,這樣很容易就吃掉伺服器上幾G到幾T的空間。

  矛盾點:更著重測試可部署性

  標準的持續交付的實踐方式是,通過基本的持續整合自動地把每個版本部署到與真實生產環境儘量貼近的模擬環境中,使用相同的釋出流程和工具。這對驗證每次提交的程式碼是否是“可以釋出”是至關重要的,但是這樣對持續整合的要求比現在大部分開發團隊正在使用的要高很多。

  舉個例子,在沒有要求持續釋出的持續整合,可能會使用Ant或者Maven將應用釋出到嵌入應用伺服器然後進行自動的功能測試。開發者使用和維護都很方便,但是這很可能不是生產環境中應用釋出的方式。

  所以持續交付團隊會自動化釋出到一個更貼近真實生產的環境,包括不同的網頁/app/資料層,並且使用在真正生產中使用的部署工具。當然,這種更像生產的部署階段更加可能出錯,因為它增加了複雜性,而且可能對開發者而言更難以維護和修正,因為這些工具更像是給系統管理員而不是給開發者使用的。

  不過這是個機會,可以和管理運營團隊一起建立一個更可靠、更易於支援的部署流程。但是實現和穩定這一流程的難度會比較大,可能會影響開發的進度。

  值得采用持續交付嗎?

  考慮到有這麼多衝突的地方,那持續交付有什麼好處,值得我們從傳統敏捷遷移過來呢?特別是對於那些實際上不太可能在一次迭代中有好幾次釋出到生產環境的團隊來說,更是要問這個問題。值得這麼做的原因如下:

  儘早發現部署可能遇到的問題以降低風險

  增加靈活性,組織可以選擇在任何時候釋出,並把附加的代價和風險控制到最小

  把生產釋出涉及的每個人拉進來(比如QA、運營等),使得整個流程更有效率。組織必須識別出流程中的困難區域,並且通過自動化、更好的協作或者改進工作方法等方式找到克服它們的方法。

  通過持續的演練釋出流程,組織會對這個過程很精通,然後釋出就會變得自動化,就像陣痛過後自由的呼吸,像生孩子一樣。

  提升軟體質量,因為團隊不能再像以前一樣把問題留到後面,他們必須現在就解決。

  消除衝突

  當引入持續交付的時候,我以上所說的衝突點就會頻繁出現。我希望當這些問題出現的時候,瞭解衝突的根本原因,可以有助於更好地討論並解決它們。如果開發者一開始不願意打破他們習慣的“正確”做事方式,或者認為持續交付所帶來的序列工作太複雜,或者很難理解這些實踐的目的和價值,那麼我希望他們可以儘量開放地給自己一個機會去嘗試一下。一旦這些實踐方式根植於一個組織並且變得成熟,團隊成員們往往會覺得很難退回到以前的做事方式。

  編者按:我重新定義了“傳統敏捷”中讓軟體可以釋出的方式。這個定義不是適用於所有敏捷實踐,但是就我看到的,大部分主流概念都認為敏捷需要停下工作來將軟體變得可釋出。








====================================分割線================================



最新內容請見作者的GitHub頁:http://qaseven.github.io/ 


相關文章