一句話概括我所做的事情就是:幫助研發團隊改進研發流程,包括使用工具、使用方法、借鑒他人經驗等方式,讓大家的軟件開發效率變得更高。
我的DevOps之路
DevOps這個詞從一出現就受到很多關注,尤其是近一兩年來變得非常熱,以致大家對DevOps有很多的誤解,這種熱度確實有一定的炒作的成分,但個人覺得任何事情的出現和流行都有其內在的原因,DevOps也不例外。
本篇簡單總結過去十年我所做的相關的事情,通過我的經歷來看過去十年DevOps在國內的發展歷程。希望這個過程可以幫助大家了解:DevOps到底是什么、是做什么的、能幫到我們什么。由于是結合我個人經驗來談DevOps,所以很多說法會帶有個人的主觀判斷,分享給大家,旨在一起探討。
第一個時間點:2005年
之所以把第一個時間點放在2005年,是因為這一年我從澳洲回到北京,組建了一家外企研發中心。在這之前我就是一個純粹的開發人員,寫code、做項目、做產品、做發布,從2005年起我的角色開始轉變,開始要去帶一個團隊,并從團隊的角度考慮問題。
當我在國內找到了幾名開發人員和我一起做一些項目的時候,我發現了第一個問題:當時我們的源代碼管理服務器處于澳大利亞悉尼,在北京如果想要把代碼提交過去非常痛苦。這種痛苦到什么程度呢?我們切入一個文件大概需要十分鐘的時間,這是非常讓人無法容忍的事情,會嚴重造成工作效率的低下。
我們找各種辦法希望能解決這個問題,包括提高網絡連接,但遺憾的是沒有找到更好的辦法。老板和微軟的關系特別好,他看到了微軟一個還沒有發布的產品——TFS(當時還處于beta版本),我們注意到這個產品是因為它的source control是基于HTTP的,所以我們決定把現在基于VSS的source control遷移到基于HTTP的TFS的source control上。從2005年開始大概持續了兩年的時間,我把公司所有的項目從VSS遷移到了HTTP。
其實VSS也是一個很不錯的source control,但當出現這種跨地域訪問的時候它的性能就會有很大的問題。這是我接觸專業的軟件工程工具或開始去想如何提高團隊效率的一個起點。
第二個時間點:2008年
第二個關鍵時間節點是2008年,當時我和微軟組織了一個叫VSTS Real World的活動,這場活動實際上就是:我們找到了很多國內有影響力的獨立軟件開發商,把其中比較資深的軟件開發人員集中到一起,讓他們去體驗如何在一個完整的軟件工程管理平臺上,完成一個軟件從需求到分析到開發到測試到打包到發布的過程。
從微軟的角度來說,是希望推廣他們的工具;從我的角度來說,是第一次完整地把自己之前在軟件交付整個端到端的流程方面的經驗分享到自己團隊之外去。
活動開發的項目是以汶川地震這個背景為假設場景,要求開發一個叫“孤兒領養”的系統。
這個項目對我個人來說非常重要,它是我作為軟件工程顧問所完成的第一個完整的項目。雖然是一種培訓的交付形式,但其實在制作這場活動的相應的資料時,我是把自己和團隊的經驗通過文檔、PPT、示例代碼的方式,整理成一整套的資料分享給其他開發團隊,并且在這5天的時間內,和大家一起完成一個真實的項目開發。在這個過程中,我們也采用了一定程度上的敏捷開發的概念,比如迭代、用戶故事等。
第三個時間點:2008-2009年
上圖中有一個關鍵時間點,標注著DevOpsDays,DevOps這個詞的出現大概是在2008-2009年這個時間段內,這期間開始有越來越多的人關注到底怎樣提升軟件研發的效率,DevOpsDays的活動是Patrick Debois 在這個時間點第一次幫助社區開始組織這樣的活動時發起的。在那個時間我對DevOps完全沒有任何理解,對于我來說,我的理解就是軟件工程,就是幫助團隊提高效率,把工具用好。
第四個時間點:2008年-2012年
在2008年-2012年這段時間里,我所帶領的外企研發團隊在業務上有一個非常大的轉型:2008年以前基本上是對外做外包,為澳洲總部做軟件外包;2008年以后開始接觸一些國內的軟件工程項目,以及研發平臺解決方案的工具落地項目,(現在我們叫做DevOps咨詢項目)。之所以從2008年開始轉型,有非常重要的外因和內因,這也是我希望通過這個過程和大家分享的。
從一個企業來說,為什么會轉變自己的業務模式,為什么會改變自己的研發模式,其實很大程度上是因為有非常強的外因逼迫你不得不這樣做,另外還有非常強的內因,讓你自己也意識到“我可以這樣做”或者說“我這樣做會比以前做得更好”。
從2008年起,我就開始在國內承接一些軟件工程類似的項目,比如研發過程改進、效率提升。我們所接觸的第一家比較大型的客戶是京東商城。之所以重點提起這個客戶,是因為對于我個人來說,這個客戶讓我對軟件工程有比較深的了解。
首先,京東為什么要做這個事情?我們在2012年開始和京東做這個項目的時候,京東整個研發團隊的規模是大概1500人,在2013年項目結束我們離開京東這個團隊的時候,它的研發規模基本翻了一倍。
以此可以看到為什么它會在這個時間點去做這樣一個項目,因為這時候如果還沒有人通過專業的角度去幫助他們梳理研發流程、考慮在這么大的規模下怎么保持研發交付的效率,可能他們在業務上會受到非常大的挑戰。
當時我們做了什么呢?我們只做了一件事情:幫助它重新梳理軟件需求上線的過程,并且通過一個工具把它相關的系統和信息收集起來,讓他們的開發團隊、項目經理、業務人員能很快做出決策,并且將一部分功能自動化。
這里一個大的背景是:我相信現在很多互聯網公司的需求上線可能仍然是采取這種模式——上線窗口,典型的是,當時京東的上線窗口是每周二和周四,它會在每周二上線一些大版本或一些比較大的改動。
為什么選擇在周二呢?周一剛進入公司可能還沒進入狀態,周二開始比較快速地工作,把精力放到工作上,這個時間點對于一個在線商城來說流量比較低,所以這時候上一些大版本是相對安全的;而另一個時間點——周四很容易理解,過了周五就是周末了,這個時間大家會考慮是不是要買點東西周末拿回家。
在京東內部,他們在每個上線時間點之前都會開一個上線協調會,這個協調會上就會出現:一個團隊說“我作為一個產品線,我想要去發布我的需求”,而另外一個產品線的團隊會站起來說“你不能發,因為我還沒有準備好”,這時候就會出現這種有意見分歧的問題,這樣的問題只有到馬上要到上線時間點的時候才會暴露出來,所以造成很多需求延遲,沒辦法按照希望的狀態被發布出去。
我們所做的系統是把這個信息盡早地收集起來,比如三周以后要上這樣一個需求,在三周之前提到系統里,系統會鏈接到需求規劃、測試、自動化打包、上線系統,這個過程中還會有一些審批的流程,把相關的一些關聯方依賴方聚合起來,幫助判斷這個需求是否能上。
其實從現在DevOps或者敏捷的角度去看這件事情,會叫測試提前,或者運維規劃提前等這種概念。在那個時候京東做的就是這么一件事情,它就是把風險盡量早地暴露出來,讓團隊能夠有更多的時間去解決這些問題,這樣的話,在真正需要上線的時候可以非常順利地完成上線操作。
通過這個項目我開始意識到:軟件開發,幾個人做的時候是比較簡單的,當團隊發展到一定規模的時候,做起來會越來越困難。這個困難的來源在于軟件開發本身是件個人英雄主義的事情,它必須要依賴于每一個開發人員的智慧,去探索創造性地解決問題,這是造成所有軟件項目管理問題的根源,也是其本質。對于軟件開發來說,沒有辦法認清其本質就沒有辦法很好地去管理它,就沒有辦法讓你的管理思路選擇適應軟件開發過程的思路而去管理這個過程,這樣效率肯定上不去。
第五個時間點:2016年
到2016年,我以咨詢顧問的身份參與到中國農業銀行的互聯網金融這個項目,去支撐和幫助他們解決在項目開發中遇到的一些問題。到現在為止,我的客戶群體在向金融行業傾斜。
過去10年間,中國大陸的微軟DevOps工具相關的所有大型實施項目都與我有關,通過服務過的企業和十年的實踐我總結出:現在最需要軟件工程過程改進,或者說需要DevOps的團隊定位是:嚴重依賴IT的非IT行業的團隊。
什么是嚴重依賴IT的非IT行業的團隊?
比如金融行業是一個非常典型的例子。首先任何一個金融企業如果沒有IT的支撐,它是根本就轉不起來的,但它自己本身的業務又是和IT完全不相關的。這就造成這些企業的客戶以及這些企業真正的業務從業人員對于IT的理解有非常大的誤差,IT人員想要在這些企業里發揮作用,就需要和完全不理解IT的人進行溝通,同時要能夠對他們進行交付,導致兩方面的溝通存在很大問題,IT人員還需要對業務進行了解,溝通成本的增加對軟件交付效率造成非常大的影響。
銀行有非常典型的溝通問題,還有一些歷史遺留問題,涉及到粒度和解耦,為什么說這兩個是DevOps實施的兩大法寶,這是我在給客戶建議或幫助他們進行過程改進的時候所摸索出來的心得。本文將重點分享這兩大法寶。
DevOps實施落地的2大法寶
不管是敏捷、精益、持續集成、持續交付或DevOps等概念,目的都是提高效率,即提高單位資源的產出。其關鍵原因在于,中國的經濟發展迅速,很多企業已經度過了那個靠增加投資來增加產出的階段,現在IT從業人員薪資在增長,所使用的各種工具和環境,包括市場都非常成熟,很難找到一種短時間內獲得爆發性收益的方式,企業之間到了拼內在實力的階段,在這個階段效率非常重要。
管理粒度。有兩層含義:1動詞,管理這個粒度,2名詞,管理的粒度。在進行研發效率優化的時候,我們要關注的就是各種粒度,需求大小、團隊大小、交付的代碼量的多少,原則是越小越好。因為軟件研發本身是一個復雜的過程,對于復雜過程的管理永遠沒辦法適應其復雜度,最有效的方式是將復雜問題簡單化,然后去管理簡單問題。所以,從管理的角度如果想優化效率就要盡量減小管理單元。
工程解耦。軟件工程涉及兩個領域:管理領域——怎么去管理過程和團隊;工程領域——實現要實現的內容,從軟件角度來說就是怎么編碼,怎么把大家腦子里的東西變成可運行的應用和服務,這個過程就是工程領域。在工程領域上想提升效率要做的就是解耦,不停地解耦,讓你的程序、服務、所有部分都可以相對獨立地被開發、測試、部署、運行,這樣整體效率才能提升上去。
軟件研發的自然屬性
建立正確的認知才能有正確的辦法。
什么是軟件的生產制造過程?
如果把軟件的開發過程和汽車的制造過程拿來比較。要制造一輛汽車,首先得有一輛原型車,這輛原型車被確認以后,汽車的生產工廠就會不停地重復生產同樣的汽車。也就是說汽車的生產過程其實就是重復生產同樣的產品。
來看軟件的開發過程,軟件每次交付的內容都不一樣。如果映射這兩個過程的話,會發現軟件開發的整個過程,包括需求、設計、開發、測試、構建、交付的所有過程都是在進行設計,而不是在進行制造。制造的過程是制造一個同樣的產品,軟件開發過程是每次產生不一樣的產品。
回到剛才那個問題,到底什么是軟件的生產制造過程?其實很簡單,就是把軟件編譯打包好,右鍵點擊zip包,選擇復制、粘貼,這就是軟件的生產制造過程。
汽車最大的人員和資源投入是在工廠里,需要大量的工人和技師讓工廠能運轉起來,制造汽車的資源投入是在重復的過程中投入比例最大,而做軟件的過程資源投入的比例99.99%是在設計過程,因為那個復制&粘貼的過程不需要這么專業的人來做。
解了這兩者之間的區別,但有沒有想過,傳統的軟件研發/軟件工程里所定義的管理方法,都是在用管理一個汽車生產線上的流程的方法來管理一個完全不同的設計過程。
這就是為什么傳統的軟件工程方法真正用到軟件開發過程中會非常難用、還會出現各種問題的原因。如果采用傳統項目管理方式來管理軟件開發過程,就相當于看到一條筆直的路,要開車從這頭到那頭,打著火、掛上檔、踩油門、松開方向盤、閉上眼睛,希望自己能夠順利地到底終點。
而事實上,結果完全不是這樣,會有軟件變更、用戶變卦、中間出現bug、開發測試理解不一致、上線過程中環境不一樣……這些問題都是無法在開發之前預見的,整個軟件開發過程是一個設計過程,是無法被預計、被計劃,和通過計劃來控制的。
這就是我說的軟件開發本身是一件個人英雄主義的事情,要靠每一個開發人員自己的創造性來解決問題,是不能通過一個看似嚴謹的環環相扣的過程來進行控制的。在軟件研發里要強調的一點:所謂計劃不是為了限制變化而是適應變化的。
敏捷讓我們重新定義管理
這就必須提到敏捷。敏捷是什么,敏捷到底幫助我們認清了什么。其實敏捷真正做的事情是幫我們認清了到底什么是軟件開發,軟件開發的管理過程到底在管理什么。
傳統的項目管理,管理的是時間、成本和范圍,它認為我們的目標是一致的,在一個固定目標的情況下,我們所要管理的就只有成本、時間和范圍。這就好像我們蓋一棟大樓,肯定是有一個藍圖的,有了這個藍圖以后這棟大樓到底需要多久蓋一層、蓋一層需要多少資源、需要多少人力投入、可能會遇到什么問題,這些基本都是可預知的。
軟件開發不是這樣,軟件開發從來沒有定義清楚我現在要蓋一棟大樓,也就是說你從用戶那里拿到的所謂的需求,永遠都是一個假設。為什么說是假設?需求和假設到底有什么區別?區別就在于:假設的價值和質量是可變的。當你的價值和質量是可變的時候,其實你拿到的就是一個假設而不是一個需求。
實際的體現點是:當你把樓蓋到第十幾層的時候,用戶過來說我要加個地下室,你肯定覺得用戶瘋了,但是從用戶的角度來說他覺得這個很正常,他認為你不就是一堆代碼嗎?為什么不能在這兒加入一行呢?他完全意識不到,他所加入的位置其實是地下室。
原因在于我們所做的軟件是虛擬的,沒有辦法被實例化,在軟件造出來之前沒有任何人能看到它長什么樣,沒有任何人能體驗到這個軟件最終會給他什么。作為一個軟件來說,只有當軟件已經被做出來給到用戶之后,用戶才真正知道這個軟件到底是不是符合他當初的所謂需求。也就是說,大家看到的需求文檔、開發計劃其實都是假設,在做出來、代碼寫出來給到用戶之前都通通有可能是錯誤的。
當我們管理這樣一個不確定的過程的時候,如果還用傳統的項目管理方式來管理它的話,必然會遇到很多問題。敏捷重新定義了軟件開發管理的思路。它定義的方式就是:把慣常的項目管理認為不變的價值和質量定義為可變的變量,傳統的項目管理領域里的變量——時間、范圍和成本,仍然是變量,所以軟件開發管理領域中的變量要比傳統項目管理中的變量要多得多、復雜得多。
這其實就是軟件研發的本質。軟件研發的項目管理和傳統的項目管理不是同一個概念,如果用傳統的方式來管理軟件研發的過程必然會遇到問題。
傳統開發 VS 敏捷開發
上圖是在比較傳統開發和敏捷開發,從過程上來其實是瀑布式和迭代式的比較。瀑布式和迭代式到底有什么區別?圖的上半部分是瀑布式的過程,下半部分是迭代式的過程。從圖中可以看到兩者最大的區別就是:迭代式的過程每一個管理單元會變得更小,交付的時間點會更加提前,實際上這就是我所說的第一個法寶——粒度。為什么敏捷開發能更加適應軟件開發過程,原因就在于它縮小了管理粒度。
當你定一個三個月的開發計劃,并且一次開始執行,如果中間出現問題,可能需要把很多東西從頭來過。敏捷開發要求我們把開發過程變成一段一段的,每一段都是一個完整的交付過程。這樣就算犯錯誤,所犯錯誤的機會成本也會低很多。
也就是說,當你的團隊規模到達一定程度,當你所開發的軟件體量到達一定程度,軟件開發必然會變成一個非常復雜的,并且你沒有辦法去把它管理好的過程。當到達這樣的量級時怎么處理?千萬不要試圖以一個非常嚴謹的管理流程來適應它,這是不可能做到的。你所要做的就是盡量減少你所管理的單元。簡單來說就是:把你的需求從Word挪到Excel里,把你的需求從一大堆的描述變成一條一條的描述,把你的團隊從幾百人的大團隊變成一個個幾個人十來個人的小團隊,把你所交付的軟件從一個單體的軟件變成一個個小的服務,這都是在控制粒度。
當你降低了粒度以后,并不是說你變得有多聰明了,而是在你同樣的聰明程度下你所處理的問題的復雜度降低了,你就能把它處理好。
總結:計劃不是用來限制變化的,而是用來適應變化的。軟件開發的計劃本身也是“管理單元”,計劃對變化的適應能力來源于計劃本身“粒度”的縮小。計劃越大越有可能沒辦法被順利執行,計劃越小就越容易被成功地執行。
軟件研發是一個復雜過程,不要試圖用復雜方法處理復雜過程,嘗試將復雜過程簡化成簡單過程,再用簡單方法處理簡單過程。
經常有人問我:我的團隊適不適合做DevOps?我的產品適不適合做DevOps?這就是個偽命題,這個問題在于你怎么看待你所管理的過程,如果愿意并能夠把管理的過程簡單化,就肯定可以做DevOps,且做DevOps的過程就是在不斷簡單化管理過程的過程。
軟件研發管理過程全景
到底軟件研發管理過程是什么樣的?如圖所示,我們要管理的就是圖上的點和線。圖上最下面比較粗的線上列出來的簡寫其實就是CMMI定義的管理過程。
用CMMI模型可視化地展示一個軟件研發的管理過程,從最左邊的需求提起,可以看到包括兩大部分的內容:
技術架構——從技術的角度怎樣來描述產品長成什么樣子,這里看到的就是一個大的產品,下面分成很多子系統,每個子系統里包含很多模塊,這就是所能看到的軟件的技術架構。
條目化需求,條目化需求就是用戶提出的一個一個的他希望軟件幫助他做到的不同的場景。
往右一點是設計過程,軟件的架構設計就是將用戶所希望實現的場景和技術架構進行映射,需要識別的是通過哪些技術可以實現用戶所希望實現的場景,并且還要在用戶場景不斷影響技術架構的過程中保持架構的穩定性、可擴展性、性能等。所以它所做的就是把底下的框框和上面的框框聯系起來。
再往右有一個項目計劃,這里我列出來了一些項目,項目里會有開發任務、測試用例、可能還會有bug等,項目是從左邊的條目化需求引過來的,這是敏捷的做法。
傳統的軟件開發的做法是:用戶想做這個事,先做分析,需要實現哪些技術模塊,然后要求把技術模塊的技術點梳理成所謂的開發計劃,它所傳遞的項目來源是來自于產品的模塊,這是一種瀑布的做法。就是在軟件開發過程中,將業務需求打散形成整個產品的完整設計,針對完整設計進行完整開發和完整交付。
它和直接使用條目化需求組織開發過程的區別在于:在你進行完整設計、完整開發的過程中,會發現到了最后收斂的時候,當真正實現了這些軟件需求,需要通過一些軟件的版本進行交付的時候,你必須要讓這些模塊的功能收斂到用戶希望的場景上。實際上你交付的還是用戶場景,只是在開發的過程中把它變成了技術語言,在最后交付的時候再把技術語言轉化為業務語言。
這兩次轉化就意味著我們必須要整體開發整體交付,也就造成了管理粒度非常大,隨之而來的就是各種問題。
敏捷開發從過程管理上要把握一個非常重要的原則:中間的開發過程必須圍繞一個一個條目化的業務需求來組織,而不是圍繞技術功能點。用戶要什么我們就開發什么,就怎樣去組織開發過程,最后交給他什么。因為就算是你把它打散成技術需求,最后交付的還是業務場景,這是沒有變化的。技術與業務之間轉化的過程,會造成非常多的問題,包括之前說的依賴問題,都是和過程的組織方式有關系的。
就這一點在我過去所服務過的客戶里一些傳統的開發團隊都非常難做到,因為這和他們現在的管理方法、組織過程以及他們對軟件開發的認知都是不一樣的。他們可能都會提我們要做敏捷,可能也會說我們要用用戶故事來進行需求梳理,但他們沒有意識到用用戶故事的時候,更深層次的要求是:整個開發過程都要圍繞單個用戶故事作為管理粒度,來推進整個管理過程并且最后進行交付。
再往右可以看到編碼、版本、運維的各種環節,代碼的變更會從開發任務產生出來,也可能會從測試用例產生出來,但最后都會被收斂到某一個版本上,而這個版本會按照順序進入到我們的開發環境、測試環境、準生產環境和生產環境,最后在環境里產生出一些反饋,再回到需求,這就形成了完整的軟件研發過程的閉環。
結合前面介紹的內容來看,如果從管理過程來理解軟件研發,管理的就是這里面的點和線;如果從工程角度來理解軟件研發,更多的傾向是:從開發測試這個環節開始,怎樣能夠讓做出來的東西更快地進入到最后的環境,并且在這個過程中保持其跟蹤性以及我們對質量的控制。
總結:研發過程改進,就是對上圖中的點和線建立對應的管理單元的過程;并將這些管理單元形成能夠快速交付需求的管理體系。
軟件研發過程:管理屬性和工程屬性
軟件研發過程具有管理屬性和工程屬性。管理屬性定義了用戶要我們做什么;工程屬性定義了我們的團隊真正做出來了什么,就是我們交付的東西,這兩個是軟件開發里非常重要的轉換,而這個轉換靠統一的版本管理來銜接。就是要建立一個統一的版本號的規范,在任何時候都可以通過一個編碼快速識別出現在軟件開發處于什么樣的狀態、現在的需求處于什么狀態、現在需要交付的東西是哪個。
至此,如果再次反思這個過程就會對第一大法寶——粒度有一個深入的理解了。軟件開發過程要管理的其實就是這個粒度,目標是盡量縮小管理粒度。在整個軟件研發體系里流動的是被管理的內容,需求、任務、測試用例、編寫的代碼、交付的模塊都是被管理的單元,管理單元越小意味著越容易管理,交付的效率越高。
持續交付就是持續解耦
前文討論得更多的是管理屬性,現在來看工程屬性。從工程屬性上我們要做的就是持續交付。持續交付到底是什么,持續交付意味著軟件一直處于可交付狀態。
持續交付本身并不完全等同于CI/CD,不完全等于持續集成和持續部署,因為持續集成和持續部署只能保證有一個可交付的產品,或者有一個可交付的代碼集并可以很快把它轉化成交付件,且在交付的過程中可以自動進行,CI/CD主要做的是這件事,而本身代碼是否處于交付狀態靠管理過程控制粒度進行保證。
持續交付實施框架
上圖展示的是持續交付實施框架,把持續交付分成了7大領域,并且把當前的實踐狀態分成了每100天交付1次和1天交付100次。實際上在任何一個團隊里,當你希望把自己的交付速度提升到每天交付一百次,那你需要從這7個領域進行規劃、設計、實施,在這7個領域里我們到底在做什么,歸結到底就是:解耦。
持續交付的挑戰:系統耦合
想要把解耦說清楚,可以從一個簡單的場景——取錢來看。站到ATM機面前,把卡插進去、輸入密碼、輸入金額、拿走現金,對于用戶來說是再簡單不過的事情,但其實這里面的技術非常復雜,在ATM機里需要處理很多的事情:機器系統控制、智能卡識別、接收用戶輸入、連接銀行系統、監控等;還要把信息和數據傳輸給銀行,這個過程中又涉及到數據加密、數據完整性、監控等;到了核心銀行系統后需要查找賬戶、賬務信息、進行審計和風險控制等。
這十幾二十個系統意味著數十個團隊和上百人的團隊規模,也就是當你把一個簡單的用戶場景從技術架構角度去看的時候,打散成技術點都會變得非常復雜,這在金融業銀行業尤為嚴重。
這樣復雜的系統造成的結果我稱之為“漣漪效應”。在一個平靜的水面扔下一顆小石子,會在水面蕩開一圈圈的漣漪,如果水中有幾顆樹,漣漪會撞到樹。如果把石子理解成需求,樹就是受到影響的系統,一個石子的場景相對簡單,嘗試一下同時扔下兩顆石子,第一顆石子扔下去蕩開的漣漪在碰撞樹的過程中會和第二顆石子蕩開的漣漪產生交叉反應,繼續影響,產生反過來的影響,這是復雜系統中分析需求、進行架構設計時難解決的問題,就是系統耦合的典型場景。怎么解耦是軟件工程領域必須解決的問題。
首先我們需要知道軟件開發中到底是怎樣的耦合。軟件開發中有三級耦合:
代碼級耦合。所有人在同一個代碼分支上同時遷入遷出代碼,也就是大家同時開發同一個產品,這種情況下團隊規模是沒有辦法超過20人的,這是一個經驗數字,想象一下一個超過20人的團隊頻繁地在同一個代碼分支上進行遷入遷出,基本上是無法工作的。
組件級耦合。不管是什么開發語言都會有包管理器的概念,比如前端可能會用到npm、bower,比如做Python會用到pip,這些包管理器所做的就是進行組件級的解耦。
組件級解耦是指:當我不是直接引用你的代碼,而是通過你對版本管理的包進行引用的時候,就可以在一定程度上延遲包的變化對我的影響,比如說我可以一直引用一個1.0的包,但是這個包的開發者已經在升級2.0,但我可以完全不理會他那條分支上的代碼變化,我就只引用1.0的包,這時兩個團隊就被解耦了,如果這是一個產品的兩個部分,也被解耦了。
組件級解耦有個最大的限制條件:到達軟件上線時間點的時候,要統一同一個應用里的所有的包的依賴。當然我說的這是一個單體應用,所有的代碼編譯到一起,在一個運行時RunTime里運行,如果是這種情況,那么包管理的隔離就只能到達產品發布的時間點,如果這幾個團隊開發同一個產品,就算在開發過程中可以讓大家去引用不同版本的包,但是如果要一起上線,那么必須在上線的時間點統一大家用的所有的包的版本,不然沒辦法在同一個環境運行。所以組件級耦合只能解決在開發測試過程中的一定程度的解耦,沒辦法幫助團隊徹底解耦。
怎樣才能徹底解耦?就會應用到現在炒得火熱的微服務,其實它所做的就是徹底的運行環境級別的解耦。
大家經常看到,很多的web api都會在url里面標識不同的版本號。比如團隊1發布了v1版本的api,并且已經被團隊2消費;那么團隊1可以繼續按照自己的步調發布v2版本的api,而團隊2可以繼續使用團隊1的v1版本的api;團隊2可以在自己覺得舒服的時間點來升級到支持團隊1的v2版本。這樣,團隊1和團隊2就徹底解耦,可以獨立完成需求,開發,測試,交付的整個過程。
這時這兩個團隊從需求、開發、測試到交付的整個過程都是可以不去互相影響的,因為就算運行時在生產環境,這個服務被部署了以后,他們都可以在不同的版本間進行切換,這樣就保證了每個團隊都可以自主地組織自己的開發過程。
實際上它就是降低了管理單元,讓管理單元可以小到一個團隊里邊,甚至小到幾個開發人員,這時可能看到的還是幾百人的大團隊,其實里面是一個一個小的獨立運作的細胞,這些細胞都可以按照自己的步調去移動、去發布、去測試,這樣大家才能更加高效地工作。
這三級解耦的過程中,團隊的自由度、業務能力、交付的速度、質量的控制都會得到提升,但也會造成系統復雜度、運維復雜度的提升,這是我們在不停地進行軟件開發解耦的過程中所帶來的副作用。
為解決這些副作用,這兩年軟件工程出現了一個明星項目——Docker,它到底解決什么問題?時間回溯到1995年,那時候經常提到一個詞:web service,當時的系統都是單體架構,甚至于整個架構里都只能用同一個開發商的同一種技術,比如C++,那就從上到下都只能用C++,沒辦法選擇其他的開發商產品,也沒辦法選擇另外的產品,原因是不同的技術棧之間的互操作性非常差,互相之間難以交互。
web service的出現就是為了解決不同技術棧之間的互操作性問題。因為從一個IT投資者的角度來說,他不希望自己被某個技術棧綁定,比如說你是一個技術管理人員,你肯定不希望說我只能招聘C++人,因為我的系統是C++寫的,你當然希望市面上流行的開發語言開發的程序都能與自己的系統融合,甚至說我現在買過來一個系統,我希望不管這個系統是用什么語言開發的,都可以和我現在的程序一起工作。這在現在的你看來可能覺得不是個問題,但在那個時候是個非常大的問題,企業IT決策者、投資者沒辦法這么自由地選擇技術棧,所以才希望通過web service去進行解耦。
這個解耦的過程一直持續到2015年,到現在你會發現不管采用什么技術棧,應用都可以進行互相操作,我們可以用很多方式去進行跨進程、跨服務、跨系統間的通訊,沒有任何障礙,這會給IT管理者很大的自由度,不再受制于技術棧,但也造成了另一個非常大的問題。
當我們選擇了很多的技術棧去開發系統,當這些系統被部署到我們的環境,你會發現這些系統是可以互相操作,從業務的角度沒有問題,但是
IT運維人員或開發人員會發現已經陷入一個非常復雜的N*N的問題矩陣。
以前我們只需要處理同一個技術棧的同一類型應用的開發、測試、部署,而現在我們需要同時處理很多不同的技術棧的開發、測試、部署。如果你用過一些開源的組件就會發現,當你在一個項目里開始引用開源組件的時候,可能你的主程序是用Java開發的、服務是另一種語言開發的、消息隊列又是另一種語言開發的,這些程序都需要被部署到IT的運維環境才能一起工作。
Docker就是用來解決這個問題的,它可以幫助你使用同樣的方式來運行不同技術棧的不同應用,這些不同應用又可以在統一的硬件和操作系統環境下被運行、被部署、被測試、被發布。解決了我們在不停的解耦過程中帶來的副作用:系統架構復雜度和系統運維復雜度提升的問題,解決了N*N矩陣的難題。
因此,在進行軟件研發過程改進或效率提升的過程中,容器技術對于我們來說是非常有價值的。
Docker對DevOps的價值有很多,如圖所示,最重要的我認為是:為不同職能/技能的人員各司其職提供了條件。
我們有很多自動化部署發布的工具,也提出來很多解決辦法,但是這些解決辦法其實都沒有Docker解決得順暢,原因在于所有這些工具的解決方式都是在采取一個更復雜的方式來解決復雜問題,試圖用復雜適配復雜,Docker是用簡單來解決復雜問題,所以它解決問題的效率會很高。
如圖是來自Google的一個統計,Docker和DevOps的發展趨勢非常匹配,DevOps效率提升的過程就是在不停解耦,解耦到一定程度后,如果不解決運維復雜度,解耦過程中產生的效率提升都會被運維復雜度吃掉,最終達不到效率提升的目的。
DevOps實施落地的總體策略
DevOps三步工作法:建立全局觀、建立反饋、持續改進。
這三步從可操作性的角度需要做什么?從建立全局觀到建立反饋的過程中,要做的是:
首先要建立端到端的軟件全生命周期管理的體系,這個體系就如軟件研發管理過程全景圖所示;
接下來把圖中所有的點適配到自己的環境中,識別出對于我來說到底是什么,同時對這個體系的管理能力必須通過一些工具來實現,這個過程就是識別管理單元;
識別了管理單元之后要做的下一步是減小管理粒度;
減少管理粒度的結果就是建立了流動性。對于看板有了解的人知道,看板最重要的原則是拉動原則,拉動原則的目的是讓進入到研發環節的內容盡快出去,所以要做的就是建立流動性。建立看板的第一步是建立管理流程可視化,這就是全局觀,看到整個過程是什么、問題在哪里,做所有這些事情的目的就是讓進入到研發環節的內容盡快出去,怎么才能盡快出去?很簡單,把這個東西變小就可以更快地流動。
有了正向的流動之后,下一步要知道流動的東西是好是壞,這就是在建立反饋,而配置管理、持續解耦(包括持續集成、CI/CD)真正在做什么?持續交付真正在做的也是建立反饋,從具體落地的策略來說,實際上是在解耦,但解耦的目的是在環節中不停地建立回答“這個東西到底做的好不好?”、“可以不可以繼續往下走?”等問題的反饋。
有了這些反饋以后,就已經形成了整個研發過程的閉環,現在要做的就是讓這個閉環不停地流動起來,這就得靠人。所以持續改進最后一步的關鍵是:人+流程。
我們的研發過程改進永遠不是一個項目,而只是一個起點。開始做這件事以后就沒有盡頭,我幫你建立起這樣一個體系以后,你要做的是不聽地改進這個體系,怎么能讓這件事情落地,要建立起這樣一個自我驅動的改進過程。
核心關注:拓步ERP系統平臺是覆蓋了眾多的業務領域、行業應用,蘊涵了豐富的ERP管理思想,集成了ERP軟件業務管理理念,功能涉及供應鏈、成本、制造、CRM、HR等眾多業務領域的管理,全面涵蓋了企業關注ERP管理系統的核心領域,是眾多中小企業信息化建設首選的ERP管理軟件信賴品牌。
轉載請注明出處:拓步ERP資訊網http://www.guhuozai8.cn/
本文標題:DevOps實施落地的2大法寶:粒度&解耦
本文網址:http://www.guhuozai8.cn/html/solutions/14019321047.html