1. 程式人生 > >百度持續交付新產品的改造之路

百度持續交付新產品的改造之路

很難 數據運營 roo 裏的 容器技術 經歷 優秀 層級 服務

本文根據黎嘉豪老師在〖2016 Gdevops全球敏捷運維峰會廣州站〗現場演講內容整理而成。

技術分享圖片

(點擊底部“閱讀原文”獲取黎嘉豪演講完整PPT)

講師介紹

黎嘉豪,百度資深敏捷教練,曾任職華為資深雲計算專家,負責雲計算中資源調度的設計和研發。加入百度後聚焦於產品級CI和DevOps,從方案、技術、工具等層面全面持續交付能力的建立,先後在百度開放雲、度秘、Simeji日文輸入法、百度殺毒等產品實施研發改進工作同時也是百度技術學院《持續交付》《研發工具鏈》等課程的講師、軟件匠藝小組講師。

互聯網時代對軟件交付的訴求

從傳統的ICT企業進入到互聯網企業後,身邊的人總會問我,我們現在處於一個什麽樣的時代?這裏我引用之前聽過的一個詞,我們現在處於的時代是一個叫做VUCA的時代。

VUCA是什麽意思呢?在過去的一兩年,我們的衣食住行都產生了很大的變化,例如我們從自己開車變成打車,從加班吃方便面變成叫外賣,跟團旅遊變成自駕遊,我們的需求在變,用戶在變,業務模式也在變,就是說,我們在做互聯網產品時,所處的環境具有易變性、不確定性,復雜性和需求的模糊性。準確來說,什麽都是不確定的,除非用戶滿意。

因此,很多時候,我們做產品都是在balance兩個要素,一個是效率,一個是質量。它們貫穿於持續交付的整個流程,也是評價的標準。這兩個詞大家應該很熟悉了,我這裏快速過一下。

技術分享圖片

效率是什麽?大家應該都聽過互聯網的七字訣,就是專註,極致,口碑和快。另外一個點,也是最近比較潮流的觀點——“只有第一,沒有第二”。通過優酷和土豆、美團和大眾點評的合並,可以看到互聯網的世界是十分殘酷的。如果你比別人慢,那不好意思,你就失敗了。關於質量方面,作為互聯網跟用戶比較貼近的一個場景,就是我們會比較講究用戶體驗、細節,還有就是缺陷必然導致用戶的卸載跟差評,此外,服務的故障必然導致市場的丟失。

但有些時候,如果為了加快產品推出市場速度,反而會適得其反。三星新手機Note 7,就是一個活生生的例子。網上有一個段子說,也許三星三個月之前就知道蘋果7這次的發布會沒有任何功能的更新,沒有亮點,所以他們花了三個月的時間把所有的黑科技全部放在Note 7裏,這使得三星不斷壓縮渠道生產質量,進而導致了電池爆炸和召回事件。可想而知,最後Note 7成為國人最容易獲取得到的大規模殺傷性武器。

看到這種案例,我覺得非常痛心,因為在互聯網做產品時,這樣的事情經常發生。所以今天的分享,我會以之前支撐過的一個項目作為背景(具體產品不便透露),講述項目最初發現的問題以及我如何帶著他們實踐持續交付,最後羅列一些從中得到的啟發,希望能對各位有所幫助。

團隊的挑戰

如何讓持續交付成為新產品的成長思維,一般的套路就是開始吹噓持續交付如何牛逼,如何讓一個產品成功。但這個我真不敢講,IBM大型計算機之父Fred Brooks曾說過,由於軟件的復雜性本質,沒有任何一項技術或方法可以使軟件工程的生產力在十年內提高十倍。簡單來講,持續交付也不是銀彈。

技術分享圖片

去年年初,有一個項目找到我們,他們當時正處於上圖的淺綠色階段,也就意味著他們已經在國際化的市場深耕了一段時間,積累了一批重視的用戶群體,希望我們能協助他們完成用戶的快速增長。

當時,我的搭檔和我一起進入這個項目,他主要負責敏捷、精益等思維的導入,我則從工程實踐方向來看,如何能幫助這個團隊。

技術分享圖片

首先,我發現該團隊已經簡單地在用敏捷,叠代地方式開發產品,對比過去瀑布的發布方式,敏捷的引入讓團隊上線部署的頻率從過去的半年、三個月縮短到一個月甚至兩周。這種模式遵循的一個實踐就是,上線的粒度越少,上線的頻率越快,同時這樣的模式比過去的瀑布發布方式更加安全。從理論來講,這沒有問題,但從實際操作來看,團隊在短時間內較難達到快速上線和質量保證同時並存,而且控制不好的話,反而會造成Dev和Ops之間的矛盾加深。

技術分享圖片

百度是一個非常講究數據、而且具備數據挖掘DNA的公司,所以早在兩年前精益創業和精益數據運營的方法論就在這個項目推廣開來,並且有了初步的效果。圖中左邊是一個精益的循環圖,剛才也講到了,精益能給團隊帶來的好處是很明顯的,可以不斷、低成本、快速地驗證想法。

但這給團隊造成了一個困惑:價值傳遞。數據監控的任務變得更多,造成用戶服務的不可用,或者會出現一些奇怪的兼容性問題。驗證、分析數據這樣試探螺旋前進的方式,讓團隊的不少成員很難適應。

具體來講,那個時候同時灰度發布驗證的版本會有3~4個,過多的分支管理造成團隊節奏上的失控,開發人員一方面在新一輪的叠代中開發需求,一方面又得為上一輪叠代收集數據和Review。所以一個同學早上可能在開發代碼,突然下午就插個需求說,你要把上一個小流量版本做一下分析,看一下效果怎麽樣。當這樣的情況不斷切換時,團隊的同學們可能就開始有點崩潰了。

技術分享圖片

這是我們軟件不斷發展時角色的分工變化。最開始還是小團隊時,我們可能一個同學就擔任了幾個角色,他可能既是一個開發,又是一個測試,產品也可以做,對這樣的工程師我們有一個稱呼,叫全棧工程師。這樣老板請一個人就能全部包辦了對不對?這樣的情況下其實特別美好,因為在整個架子的流轉過程中,沒有任何數據的丟失。當我們團隊開始人多時,這種小完美的狀況就有種一去不復返的感覺了。

因為團隊成員的增加,一方面我們要投入培訓的成本,另外人多後,同一個團隊不同職能的同學容易陷入煙囪式的發展。當大家各自的出發立場不一樣時,就會發現在一個團隊不同職能的小組裏,開始出現了一堵無形的墻。當開發、測試、運維相互價值流動時,就變得像以前在學校傳紙條那樣丟過去,這樣的模式無疑是低效、並且常常會在傳遞的環節造成信息的浪費與丟失,無法滿足我們業務快速穩定的增長。

回顧這幾年的發展,特別是研發(RD)和運維(OP),我們來看看他們的演進。

技術分享圖片

這裏有一張圖,從左邊到右邊過一遍。在開發領域裏面,我們經歷了從傳統的瀑布方式到敏捷再到DevOps模式的演變。關於技術架構,我們也不斷地更新,最早時的架構我們叫大合創,就是所有的代碼支撐、構建部署、交給客戶、上線都是那一個,這樣的產品龐大起來之後,就變成了中間一個多層次的分層架構。到了這幾年我們發現分層也有瓶頸,現在推行的是微服務的架構。微服務架構能帶給開發的一個好處就是,服務的粒度更小,而每個功能都有單獨的API接口,開發和部署周期越來越短。

在運維領域,有兩個點很重要,一個是部署和打包的變化。最早我們是直接部署在物理機裏,慢慢地改成部署在雲主機,再到現在的容器。部署的方式不一樣,底層的基礎設施架構也在升級,從最早的自己組建數據中心、到之前聽到的魅族把主機寄投在其他IT機房裏,再到現在壓根就不用我們去管機器,直接用雲這樣的模式變遷。

技術分享圖片

所以我們看到,在這幾個領域裏面,開發和運維都在不斷更新各自的工具,開發因為技術的提升,部署的節奏粒度越來越細,部署的頻率則越來越快;運維的同學們則希望線上穩定,對上線的代碼時刻警惕,擔心會破壞線上服務。

獨立的兩個團隊如果發展有一段時間的話,他們所用的工具和技術就會有隔閡,具體講就是相互不太理解對方的工作方式和原理,久而久之,就會在上線或者代碼回滾的流程中出現一些問題。通常來講,這不會出現在一般的上線流程中,但在小流量的上線或上線失敗時,RD同學就會因為不熟悉工具踩到一些坑。

所以在項目組裏,我們深信有一條路,這條路可以讓項目組的同學輕松一點,但這條路也不是那麽平坦,也存在很多問題。

技術分享圖片

例如進度不可控,在我們的項目裏面,會經常聽到RD同學這樣說。第一天RD同學很開心地說他已經完成了60%,第二天他仍然很開心地說已經做完了90%,那按往常來講,這個東西到第四天、第五天肯定可以上線了,可事實不是這樣的,在第三、第四天我們會發現RD同學的表情開始有點惆悵了,然後他在匯報進度時會說還是有問題。為什麽呢?因為RD和項目經理對需求的概念不一樣,RD更多覺得做需求就是看開發的進展怎麽樣,他沒有考慮到系統測試、提前測試和上線的一些因素,導致了項目的進度比較難把控。

第二點是流程不可靠。當一個小完美團隊往大團隊發展時,必然有幾個支撐RD和運維的人站出來,由他們來掌控產品的整個流程。整個產品怎麽開發,怎麽上線,只有他們最清楚,其他的同學都不太清楚。這就會導致整個團隊運作不起來,特別是如果這些同學離職了更會給團隊造成明顯的壓力。

第三點是環境不穩定。我們經常會聽到這麽一句話:這個軟件在我的機器裏部署沒有問題,為什麽到了你的機器那就有問題了?當我們沒有統一機器的時候,這類問題經常發生。而且對RD來講,這個問題要不要去定位是很難把握的,因為有可能這個問題出現了一次後就不再出現了。

第四點是協作的不順暢。就像前面講到的,每個角色在價值流動時,都會有一堵墻,把信息中斷了。還有很多問題,例如分支過多、合並困難,缺陷爆發、測試受阻,環境公用、未知錯誤,以及版本混亂無法回溯等等。

所以,當時我一直思考,用什麽方式能幫助項目組解決這些問題。

我們的目標

技術分享圖片

讓我們回到敏捷宣言的第一條,我們做產品就是為了快速、持續不斷地將有價值的軟件交付給客戶,並且希望他們滿意。這是指導項目進行軟件開發的價值準則。所以,版本我們要發,穩定也是需要的。怎麽做到這個最終目標呢?這裏項目組當時和我一起分解了幾個小目標。

技術分享圖片

  • 縮短提交代碼正式部署上線時間,降低風險

  • 能夠自動的、快速地提供反饋,以便及時發現和修復缺陷

  • 能夠讓軟件在整個生命周期處於可部署的狀態

  • 能夠按一下按鈕,就能將任意版本、按需部署在任意環境中

  • 能夠讓整個交付過程變成一種可靠、可預期、可視化的過程

打造一條可視化的持續交付流水線

技術分享圖片

首先,我把團隊所有的人都拉在一起,有RD、QA和運維,讓大家腦袋裏面的想法通過落地於流水線而讓全部的成員知曉。這是當時畫的一個圖,這個圖中還有一個特殊的點,就是我們要組建自動化,但不能說把所有東西交給機器,必須設置一些小人即我們人工review的環節來確保版本上線時是可控的。

例如,那天的討論會就能聽到上線環節復雜時,RD在體測環節還有發上線單環節提出了自己的怨聲,說好幾次填錯版本號,運維的工具也沒有提示這個版本是沒有經過QA測試的,導致上線了錯誤的版本。而且回滾的時候還需要填寫歷史的版本,為了查詢上一次的版本號信息,又耽擱了十幾分鐘。

當RD說完這番話之後,運維的同學就開始跳起來,說為什麽不安排他們的同學來上線,RD說申請了,但是等待上線的任務太多,版本需要緊急上線,來不及了。

所以,後面我們以敏捷宣言的準則,和RD、QA、運維的同學畫出了下面的流程圖,對比上面的環節,我們可以看到整個流水線的步驟增加了不少,但是每個流程之間基本都是自動觸發的,而且每個角色的同學都很清晰自己負責的範圍。一旦這個流水線建設好了之後,與會的所有同學便都有信心來操作上線步驟。這個在過去是無法做到的,大量的上線任務都只能靠運維或者RD來執行。

組成流水線的元素

技術分享圖片

如何組成這樣一條流水線?我這裏講6個點,不是很多,但這每個點都是必不可缺的。包括配置管理、構建管理、持續集成、測試管理、環境管理和部署管理。每一個元素在流水線上都有它存在的意義。接下來我挑幾個來講一下。

  • 配置管理

技術分享圖片

傳統來講,我們認為配置管理就是代碼的管理,實際上它的定義遠大於這個。凡是我們引進研發裏的所有變更,都屬於配置管理的內容。除了版本管理,還要組建依賴管理,我們依賴的第三方組件的版本是什麽,這些都要記錄下來。另外一個點就是軟件配置管理,一般來講軟件和配置是分開的,為了適應多環境的部署,在這裏要管理起來。最後經常被遺漏的一點就是環境管理,很多時候我們想部署回去兩個月或者一年前的版本,但是失敗了,就是源於我們的內核和基礎設施的變更。凡是這些相關的都要管理起來。

在這裏,除了剛才講到的全面配置,再把配置管理裏面我覺得比較重要的點分享一下。

技術分享圖片

這是我們的分支策略。

在百度內部,我們推薦主幹開發、分支發布這樣一個模式,我們希望QA在分支上進行一個補充測試,如果有bug的話,我們的RB測試就會在分支和主幹裏面進行修復。如果上線發現bug的話,我們也可以很清晰的有一個分支與之對應。

前面我提到精益到了一個團隊裏面會出現一個問題,就是很多線上的訪問無法跟蹤,很多跟著跟著上線後就死掉了,這時候我們引入一些叫feature flag(特性開關)的功能到架構裏,希望能夠讓一個branches裏面的產品在線上根據機器的不一樣來展現不一樣的特性,從而滿足精益試驗的效果,減少過去特性分支的拉取。所以我們會比較嚴控地去拉分支,避免線上過多版本的跟蹤。

技術分享圖片

Check in dance, 這是多人開發、代碼合並、持續集成的俗稱說法,有8個點。作為一個RD你要提交一個代碼時,你要check out代碼,執行本地構建沒問題了,再check out代碼,避免跟別人沖突。在執行本地構建沒問題後,再提交到主幹,等待主幹上的編譯、持續集成的結果,如果失敗了,不好意思,你要再來一次。

但是到了敏捷,我們不再走這樣一個老套路。我們引入了Gerrit的評審流程,把更多的東西交給機器去處理,準確來講,我們的RD只有兩個鍵,一個是拿去代碼,另一個是提交代碼,這裏和過去有什麽區別呢?意味著我作為一個RD,我只需要把我的代碼提交到庫上面去,可這時代碼是沒有入庫的,我們的評審系統會很智能地把主幹上最新的代碼加上RT這一次提交的代碼,自動合並成一個提交、評審,再交給自動化測試流程。只有自動化測試流程通過了,我們的RD經理才會讓它評審通過,並且具備合並到主幹的權限。合並到主幹的權限後,還有下一個持續集成的流程,去驗證我們的產品集成後有沒有問題。

  • 構建管理

技術分享圖片

接下來講一下構建管理的優化。在我們原來的編譯中,構建管理是自己的本地機器或項目組裏的機器去進行的,後來項目組為了縮減原來12分鐘的編譯時間,設置了一個叫“1-5-10”的法則,我們希望的構建是一分鐘最好,5分鐘是一個比較優秀的階段,超出10分鐘是不能接受的。我們引入公司的編譯集群,把我們的編譯用戶分發到公司所有可以接這個業務的機器上面去做,並且這些機器都是針對編譯進行過CPU的優化。

同時,我們的構建任務也一改過去的Push,改成拉取的狀態,這是個很有意思的問題。舉個例子,過去想編譯一個版本,我們的組件可能會依賴三個外部的庫,我們一次構建,會拿外部的庫的代碼下來,然後觸發構建,再一起build,這樣的模式我們稱之為Push。構建自己的模塊時,也需要把外面的庫構建一遍,比較浪費時間。後來我們就改成Pull,只care自己的那一塊,其他人可能會隨時開始觸發構建,並把最新穩定的編譯結果放到一個產品庫裏,當我們需要構建時,只需對它們進行一個拉取編譯,速度比過去快了很多。

  • 持續集成

技術分享圖片

持續集成的話,就是給團隊不斷深化,這裏也給出了一些原則,包括:

  1. 頻繁提交

  2. 主幹上做持續集成

  3. 至少每天進行集成

  4. 自動化構建和測試

  5. 分級測試快速反饋

  6. 紅燈需要立即修復

  • 測試管理

技術分享圖片

技術分享圖片

關於測試,我們組建了一個分級的Jenkins,嚴格把握時間的分級測試。此外,我們通過建立分級測試體系,保證編譯和測試結果盡量保持在10分鐘之內就有一個基本的校驗。

  • 環境管理

技術分享圖片

這是百度內部容器管理的架構圖。我們OP和RD的同學組建了三個層級的容器服務,包括服務管理、資源管理和機器管理。這樣的好處是讓OP和RD都有自己的視圖去看他們關心的東西是否良好,從而避免過去運維系統的復雜和難使用。

技術分享圖片

對比容器和虛擬化,這裏講一下我的經驗,因為我過去在華為和百度裏面很明顯看到這樣的區別。過去我在華為做私有雲、公有雲產品時,經歷過最早的物理部署、虛擬化部署的環節,虛擬化部署時有一個問題,就是當軟件OK了之後我們要進行虛擬機的鏡像,這個過程一般是40分鐘,打出的虛擬機鏡像大概是6個G。一般來講這沒什麽問題,但我有一次在德國給客戶演示,發現這個等待的過程是痛苦的。

所以容器技術誕生的時候,它把虛擬化這個難點給解決了。容器做拉取不用一分鐘,你的服務就OK了。然後去編譯打包這個容器時,也很快,跟平時的編譯時間差不多。還有就是它非常的小,一般600~700M就一個容器的鏡像了。

  • 部署管理

技術分享圖片

我們把部署管理裏面的流程變成可配置化,把它作為一個表述語言的方式來控制話,從而達到某一個目標。

技術分享圖片

這是我們的灰度發布,通過組建,將線上的一些環境分成等級,讓我們的部署系統可以先發布一部分的流量,驗證沒問題了,再去做流量的發布,並且小流量的發布也基於這樣的策略來實施,這樣的發布好處是讓整個過程一目了然,並且回滾的策略也已經配置好了。所以每個同學都會很有信心地去操作。

最後,這是我在百度裏面跟同事一起歸納總結的關於持續交付幾個管理的實踐總結:

技術分享圖片

交付流水線

技術分享圖片

這是我們的系統,整個從構建到發布為一條線。大家可以看到右邊有一些點,就是員工的審核點,都需要在員工的驗證之後才能進行下一步操作。每個同學的情況也很清晰,究竟我的這次提交掛了沒有。

數據度量和分析

技術分享圖片

這是我們數據分析的報表。因為信息的問題,我只能截一些抽樣的圖。我們可以很快地看到上線的效果是怎樣的。

持續交付技術棧

技術分享圖片

這是比較復雜的一張圖,包含了百度整個工具鏈,從開發、運維和測試的一整個平臺。左邊是開發,中間是測試,右邊是線上容器和部署平臺。DevOps的技術有很多,我們只選取我們所需要的,組成這麽一個架構來滿足團隊的使用。

持續交付效果案例回顧

技術分享圖片

這是一張持續交付效果圖。從過去一個比較長的發布周期,到縮短了一半的時間,這是很了不起的效果。當我統計了後跟其他人分享,都覺得這很不錯,因為我們沒有刻意去引入一些什麽事情,我們就是把整個工具鏈建立起來,把DevOps的思想安利給團隊,結果我們就得到了兩倍產值的提升。

技術分享圖片

測試周期、部署、交付也得到了一個非常好的變化。以前我們一天只部署三個,因為再多, OP受不了了,現在所有組件加起來,我們一天基本部署10次左右。開發到上線交付的周期縮短了53%,並且各個角色基於交付流水線緊密協作。最後做到的效果就是快速交付,保證質量,降低風險。

技術分享圖片

最後給各位,也是給我的老大匯報時的一個Judgment,你吹了那麽多BB,怎麽知道你的持續交付就這麽厲害?我們只有兩個評價的標準,第一個,修改一行代碼從修改到上線需要多長時間;第二個,我們這個流程是否是可重復且可靠的。

技術分享圖片

百度持續交付新產品的改造之路