DevOps,不是一個傳說!
DevOps最近成了熱詞,望文生義,你也能猜個八九不離十,它就是在說"研發團隊"與"運維團隊"之間的那點事兒。那么,到底什么是"DevOps"呢?
WikiPedia上說:"DevOps是軟件開發、運維和質量保證三個部門之間的溝通、協作和集成所采用的流程、方法和體系的一個集合。它是人們為了及時生產軟件產品或服務,以滿足某個業務目標,對開發與運維之間相互依存關系的一種新的理解。"這恰好體現了精益管理中的客戶價值原則,即:以客戶的觀點來確定企業從設計到生產交付的全部過程,實現客戶需求的最大滿足。我們也可以把DevOps看作是一種能力,在缺乏這種能力的組織中,開發與運維之間存在著信息"鴻溝"。
如何獲得這種能力呢?關鍵有兩點:一是全局觀:要從軟件交付的全局出發,加強各角色之前的合作;二是自動化:人機交互就意味著手工操作,應選擇那些支持腳本化、無需人機交互界面的強大管理工具,比如各種受版本控制的script,以及類似于Nagios這樣的基礎設施監控工具,類似于Puppet、Chef這樣的基礎設施配置管理工具。
有人評論說:"針對目前國內情況,DevOps還是很遙遠。也許只有行業頂尖的公司,或者新成立的公司會有這樣的嘗試。大多數的企業還未開始進行敏捷的推進,傳統的重重阻礙會使敏捷的推進進程遙遙無期。" DevOps真的離我們有那么遠嗎?DevOps應該從哪里開始呢?
一、讓數據說話
讓我們看一看百度某產品線在半年內的變化吧。首先要說明兩個百度術語。"提測"是指某個項目開發完成后,在正式上線前,將其提交給測試組進行測試的活動。對于客戶來說,"提測"這個動作本身并不增加什么價值,但也需要花費一定的時間。"上線"是指某個項目驗證合格后,將其部署到服務器的過程,其中包括"上線申請"和"實際部署"兩個活動。也許在各公司中對這兩個活動叫法不同,但在軟件生命周期中,"提測"、"上線"這兩件事無論花長時間,大家可能都不會感到奇怪。下面兩張圖是該產品線進行改進之后的對比數據。
從圖中不難看出,提測和上線部署的效率已大大提高。象百度這樣的互聯網企業,產品線多得數不清,幾乎每個產品線每周都有新功能部署。僅從這兩個數據來看,其收益可想而知。那么,半年前的狀況是什么樣的呢?
二、流程建模
既然DevOps關注于價值交付的全過程,那就讓我們看看該產品線常見的交付過程吧。
對于單個項目來說,它大體上是一個典型的瀑布開發過程。首先是需求收集與整理,撰寫MRD(Marketing Requirement Document)或總體設計后,進行評審。如果涉及到多模塊,每個模塊的開發人員會對各自負責的模塊進行詳細設計,給出大致的開發計劃,并商定聯調時間點。之后,開發人員會從主干上拉出項目分支,并在該分支上進行開發。當到最后聯調點時,幾個開發人員才會在將代碼合在一起,進行聯調。當調通之后,開發人員再申請提測。測試人員接到提測申請單后,進行測試,記錄Bug,通知開發人員修復,直致質量達到標準。之后,開發人員會填寫上線申請單,經運維人員確認后,運維人員操作進行上線部署工作。如圖所示。
開發的復雜性還在于:該產品線有很多并行項目,為了避免互相干擾可能帶來的沖突,每個項目啟動后都會重新在主干上拉出分支,在上線前才進行合并。如下圖所示。
另外,并行項目太多,導致每個開發人員會同時參與多個處于不同階段的項目。那些周期較長的項目雖然會被分解成多個迭代,但每個迭代內都是同樣的開發流程,只是最后僅有一次上線而已。
總而言之,突出的問題表現在:
- 同一角色多個人員的合作開發;
- 各角色部門之間的協作以各自的產品物為目標,如MRD、產品代碼、測試用例、上線操作單;
- 基于人機交互方式的內部流程管理平臺。
三、發現浪費
從精益思想出發,為了盡早交付價值,必須首先找出整個流程中的浪費,并將其消除,從而提高流程效率,讓"一個想法從提出到實現"可在最短時間里完成。那么,浪費到底表現在哪里呢?
- 一些不必要的多分支開發,合并后發生問題的風險高。多個項目中可能都要修改同一個模塊的代碼,每次在最后合并代碼時都會出現一些問題,非常痛苦,尤其是修改比較大的時候,合并及修復時間較長。
- 推遲問題被發現的時間。每個開發人員會將需求分解成多個技術任務后開發。所以,所有任務完成之前,應用程序一直處于不可用狀態。當最后在一起聯調時,常常會發現一些意想不到的問題。
- 基于流程平臺的溝通。在提測環節中,溝通完全基于內部項目管理平臺和即時消息工具或Email。比如開發人員在提測前,需要在項目管理平臺上申請該項目的4位版本。拿到4位版本后,才能提交平臺統一編譯。如果編譯失敗,那么問題解決后還要再次申請4維版本。如果成功,則在項目管理平臺上填寫表單,回答一系列的問題(比如,是否做過單測?測了哪些功能點?部署步驟是什么?),發起提測工作流,管理平臺會自動發送電子郵件給相關測試人員,通知他們進行測試。測試人員收到該提測工作流后,必須在平臺上進行相關確認操作,通知開發人員已收到該版本。如果測試人員對部署和測試內容有疑問的話,還會通過即時通訊工具或郵件與開發人員進行確認。
- 常規的例行工作很難自動化。上線部署也需要通過內部平臺來完成。開發人員拿到已測試通過的4位版本后,先要登錄到內部平臺,再提交上線申請單,填寫上線步驟。當運維人員收到上線步驟后,再將其"翻譯"成平臺可以識別的"半自動上線步驟",再讓平臺來執行。如果運維人員不理解上線步驟,就要和開發人員通過電子郵件或即時通訊工作等進行反復確認。部署配置信息分散在各處。如下圖所示:
另外,該產品的一個重要特征是需要不斷地嘗試調整程序算法策略,以得到最佳的流量效果,而這種調整的頻率較高(至少每周一次)。當需要調整策略時,開發人員修改代碼后重新進行編譯打包,由于產品代碼發生變化,所以測試人員仍需要進行大量的回歸測試,而運維人員在部署時也需要將對二進制文件包進行整體部署,整個周期比較長。
從上面這些內容中,我們不難發現,流程中更傾向于將問題推遲到后面解決(比如最后集成聯調),將工具(平臺、郵件、即時通訊)作為協作的基礎,而角色間的溝通幾乎完全依賴于前一個環節的產物(比如MRD、產品代碼、上線步驟)。那么我們使用哪些對策進行優化,達到消除浪費的目的呢?
四、應對措施
1. 無人工干預方式的腳本自動化
- 自動化提測——由于已做到了每日集成,所以每天都有可測試的版本,開發人員不再需要為提測進行專門的準備工作,只要從成功構建的列表中選擇一個給測試人員就可以了。使用Hudson平臺后,通過插件即可調用自動化腳本,完成提測版本的標識。
- 統一配置信息源——將所有的配置項全部放在Subversion庫中進行版本控制;并根據應用環境的不同,分別保存在Dev,Test和Online三個目錄中。
- 常規流程腳本化——經過各角色的共同討論和可行性分析,最后配置上線部署的實施方案是:由開發人員將產品二進制包與配置項進行剝離,這樣僅做策略調整時,測試人員只要對已修改的配置項進行相關測試即可。運維人員用一系列的腳本代替了內部運維平臺的手工上線操作,再通過Hudson平臺的插件,以 "Click Button"的方式達到了一鍵式部署。
2. 盡早發現問題,解決問題
- "需求細分,及時開發,及時驗證"——將需求拆分成端到端可測試的需求(即"用戶故事"),這些需求一般可在3天內完成。在實現每個需求之前,開發人員與測試人員進行充分溝通,對需求與驗收條件達成共識。每開發完成一個用戶故事,就進行測試,并用自動化測試進行覆蓋。
- "主干開發,分支提測"——將原來的多個分支進行合并,統一在主干上開發,每周結束時拉出一個分支,進行提測,一旦發現問題,就在主干上修復。
- "持續集成"——為了確保每次提交質量,對主干開發建立持續集成環境,開發人員和自動化測試人員都嚴格遵守持續集成紀律"Check-in Dance"。
新的開發流程如下圖所示。
分支開發策略變更為Single Branch模式。
五、小結
通過以上改進措施,讓團隊的合作方式發生了重大變化,從"碉堡防御"走向了"戰線統一"。
原來,各角色僅關注于自己本身的工作,雖然大家都同處于一個項目中,但各自劃分了"領地",產品經理就應該將MRD寫得清清楚楚,如果開發人員認為不清楚,那就回去再改。開發人員只管按照MRD上的內容進行開發,很少考慮可測性和易測性問題。測試人員只管按照MRD中內容來測試,有問題通過內部工作流平臺提交問題單。運維人員只管根據開發人員提交的上線操作單進行操作。似乎各角色之間的溝通介質只有各自的"交付物"。
現在,各角色都能夠共同合作,以項目的最終交付為目標,積極討論需求,優化實現。因為角色之間的這種緊密合作讓所有人對不同角色都有了深入的了解。開發人員耐心為產品經理解釋技術實現,說明計劃安排,測試人員與開發人員共同討論驗收條件,避免遺漏需求。開發人員讓運維人員了解架構設計, 細心聽取運維人員的建議,進行技術改造,使部署工作更快捷有效。
通過這些活動,大家都認識到原有內部管理平臺僅是個公文流轉的支撐平臺,要想提高工作效率,就要將這種"辦公自動化工具"進一步提升為"全面自動化工具",使所有人更關注于端到端的價值,而非各角色之間的分界點。
六、結束語
百度剛剛開始敏捷之旅,還沒人談及"DevOps"運動,雖然還沒有什么強大的工具支撐,但基于"提高效率"的樸素思想進行的過程改進也帶來了"DevOps"效果。可見,DevOps聽上去很神秘,但其實并不難。只要本著精益思想,聚焦于快速交付價值,不斷發現并消除浪費,你也一定會有很大收獲。