標籤:

豬八戒網的DevOps進化論

一、寫在前面

1、豬八戒網的系統架構演變史

圖1 豬八戒網架構演變過程

2015年前,豬八戒網80%的項目都是php語言開發的,剩餘少部分系統使用nodejs和java。2015年一個關鍵的里程碑,開啟了豬八戒網SOA服務轉變,這就是騰雲7號行動。

騰雲7號可謂意義深遠,它使用java語言將核心業務代碼進行了重構,建立了以dubbo為核心的SOA服務框架,使用zookeeper+swoole為核心的業務調用提供機制。

滿足新業務使用java語言編寫、老業務仍然使用php編寫,同時支持兩種語言調用dubbo服務的能力。

圖2 SOA項目系統架構

2、開發語言變遷

在SOA架構的基礎上,2016年開始全面推行前後端分離,於是出現了三足鼎立的局面:

1、nodejs:負責前端

2、java:負責後端及老php項目遷移

3、php:負責老項目維護

剩餘部分小系統或者邊緣化的工具使用其他語言開發,或者在此三種語言基礎上的一些變種:

圖3 開發語言演變過程

3、瘋狂增長的背後

系統架構以及語言體系的變化,隨之而來的是項目工程的指數級增長:

圖4 項目增長走勢圖

項目工程的增長,給軟體研發過程管理帶來了較大壓力,這時候公司開始推行敏捷。

圖5 敏捷項目管理與發布

區別於業界流行的敏捷開發模式,豬八戒網根據公司實際情況做了一點小小的變化,即增加了deploy的概念,整個層級變成:deploy->story→task

deploy是story的集合,作為一次上線發布的內容匯總,它主要負責從開發到測試到運維的交付件說明,以及開發-測試-性能-預發布-灰度-線上各環境代碼發布的准入准出標準控制,deploy這部分將在後面DevOps中做詳細介紹。

業務擴張對運維又帶來了壓力,大量的項目需要進行發布,所以虛擬機的數量也不斷增長,管理難度隨之加大,運維人數最多增加到三十多人:

圖6 伺服器數量

為了降低維護難度,我們開始做CMDB,指定各種規範,同時進行多數據中心建設,業務上做異地雙活。

圖7 多數據中心建設與異地雙活

nginx載入upstream進行灰度和生產環境流量控制,DNS負責數據中心切換,能達到在某個數據中心掛掉的情況下快速切換到另外一個數據中心。

敏捷開發、快速增長的項目工程、不同語言的編譯構建、不同數據中心的部署和代碼發布、不同數據中心和不同環境之間的服務監控以及反饋鏈路,如何滿足這些需求並且將它們連起來,這是豬八戒網需要解決的重點問題。

二、DevOps進化論

為了滿足業務快速擴張的需求,2016年末開始組建DevOps團隊,集合了運維、配置管理、java技術人員等。團隊專門負責DevOps方法論以及技術的落地,全公司使用統一的標準進行軟體開發,並使用統一的工具進行項目管理。一張圖看豬八戒網的DevOps:

圖8 豬八戒網DevOps全景圖

上圖中的DevOps是一個平台,它集成了從開發到測試到上線的整個過程,基於這個圖重點介紹:

1、新建git工程

在2016年開始,公司搭建了gitlab,後來發現gitlab和svn大家都在用,那麼整個發布系統需要支持兩種版本庫(那個時候的發布系統並不是jenkins,而是公司自己開發的syn2,基於Django框架的python前端,調用後端shell實現編譯構建和發布),雖然當時都支持了,但為了統一版本庫,降低維護成本,我們關閉了svn,將所有svn項目遷移到gitlab中;

同時我們提供了java的dubbo和api工程模版,nodejs的兩個框架工程模版,用戶在DevOps平台可以直接選擇工程模版,然後自動創建一個git工程並返回給用戶git地址。

2、構建

針對開發語言的不同,我們提供了12種編譯方式,分別為:java、php、nodejs、utopia、scala、gnode、jello、fis、html、tpl、thrift、blg。

針對不同的編譯方式,我們提供了不同的jenkins構建環境,當然,我們把它集成在了一起,jenkins採用master/slave的架構,支持任何語言的編譯,jenkins將在後續介紹。

3、發布組件

java的組件,構建後發布到nexus組件倉庫,原來我們的nexus組件倉庫不受控制,開發人員可以隨意上傳組件,不管是snapshots還是release,所以導致很多release版本問題,後來我們做了許可權控制,發布也統一起來,開發人員可以在本地將snapshots上傳到nexus倉庫,但是release的必須使用DevOps提供的能力上傳,這極大的保護了release版本的穩定性。

圖9 java組件化統一發布標準

4、發布API

java的API介面實現,這裡有三個功能:發布組件到nexus倉庫、自動生成API介面文檔、將代碼轉換為php和nodejs生成物(這裡沒有歷史,只有今生)

圖10 API服務統一標準一鍵發布

這三個功能用戶可以一鍵觸發,所以任何部門的API介面,只要一發布,必然有最新的介面文檔,避免了介面文檔認為更新不及時的問題。

5、發布流水線

流水線的演變是基於測試環境的變化而變化的,曾經我們的測試環境比較單一,流水線也相對簡單,但隨著業務的快速發展,單一的環境凸顯大量的問題,所以我們開始在環境和流水線上進行優化改造。

曾經豬八戒網的測試環境都是由DevOps團隊統一管理和維護的,隨著環境和流水線的不斷優化,後來交接給運維團隊負責,目前已經在慢慢將測試環境交給開發和測試自行維護,但大家意識上還是比較多的依賴於DevOps和運維幫忙解決環境上的問題,這裡先介紹流水線上發布模式進化的三個階段:

1)、第一階段:我們叫它大鍋飯年代

圖11 發布流水線大鍋飯年代

這個時期的流水線很簡單,環境也很簡單,問題點主要也就是上圖中的情況。

2)、第二階段:又叫公交車模式

在這個階段,我們的系統架構還沒有dubbo,這次調整隻是為了解決環境共用導致的相互影響,所以搭建了t1、t2、等t系列測試環境。測試完成後將代碼合併到trunk推送預發布,在預發布做回滾測試,上線時直接將預發布的代碼同步到生產環境,保證預發布的代碼和生產環境代碼一致。

圖12 發布流水線公交車模式

公交車模式解決了第一個階段提到的1和2兩個問題,但項目仍然耦合。所以我們以公交車模式通過降低線上變更頻率【每周二、四15點,公交車司機準點發車,將預發布上的代碼同步到線上(並不是將trunk代碼發布到線上)】來達到耦合帶來的問題;雖然解決了一部分問題,但隨之而來的需要大量人工勞動力去維護這大量的測試環境,環境一致性問題隨之突出;

3)、第三階段:也叫計程車模式

圖13 發布流水線計程車模式

為了解決項目的耦合問題,以及環境一致性問題,我們開始給每個項目指定開發負責人,這種責任人制度,很大程度上解決了耦合的問題,大家都開始將各自負責的項目許可權收起來了,業務範圍和邊界更清晰。同時引入docker技術,實現構建一次處處運行,解決了環境一致性問題。分支策略也變得非常簡單:branches開發,master發布,tags存檔。大家可以在此分支策略基礎上做任意變種,滿足各個事業部不同開發人員的工作習慣。

在計程車模式發布的各個環境里,使用了在敏捷階段介紹的deploy,每個環境推送,都必須指定一個deploy,這個deploy必須和你推送的項目工程有關:

圖14 發布流水線研發流程式控制制關聯

deploy必須到了某個階段,才能推送對應環境,而deploy的每個階段都有準出檢查。

這就像一條河,河上有幾個壩,每一個壩都會攔截一部分河裡的垃圾,那這條河的下游相對上游肯定是更清澈乾淨一些,最終匯入大海的水才會清澈,海水就是我們的生產環境。

圖15 發布流水線一級視圖

每一個節點(環境)又有各自的流水線,各節點下的流水線:

圖16 發布流水線二級視圖

所以我們的流水線是二級流水線:第一級流水線對應我們的五大環境(測試環境用戶可以自定義環境名稱,所以又有子環境的概念);第二級流水線對應各環境所需要的原子任務組合。

所有功能我們做成原子任務,包括校驗類和執行類。每個節點(環境)可以自由組合需要的原子任務(必須的原子任務由後台控制,非必須的原子任務由用戶自行選擇是否添加)

3.1、校驗類:我們在執行任務之前,有很多校驗(此類任務一般使用java實現),包括前面提到的和敏捷關聯的deploy的流程校驗,以及安全掃描是否通過,配置中心是否配置,告警中心是否有對應告警等多達十幾個校驗項;

3.2、執行類:各種校驗內容通過後,才進入到執行類任務,包括從gitlab拉代碼,編譯構建,上傳製品庫,發布到代碼源伺服器,docker鏡像製作,上傳harbor倉庫,啟動容器等,其中大部分功能是jenkins來完成的。

為了保證流水線的高可用,設計了jenkins的多master+多slave的架構,具體架構情況如下:

圖17 流水線核心架構

因為jenkins的許可權機制無法滿足公司業務需求,所以我們將jenkins放在了後台,用戶不能直接接觸到jenkins,而是使用DevOps作為用戶入口進行調度。

DevOps集群隨機調度到對應的master上,當DevOps在創建jenkins的job的時候會在所有master上面創建;當DevOps在觸發jenkins構建的時候會隨機選擇一個master執行(當某個master異常,DevOps不會調度到該master,當master恢復正常後,後台任務會自動將多個master間的任務置為一致),slave放在kubernets集群中,當slave隊列滿的情況下可自動增加slave節點(構建docker鏡像的節點仍然在虛擬機中)。

jenkins上的任務首先以項目工程為單位建立folder,再在folder下建立對應的執行類任務。我們沒有使用jenkins的pipeline的原因,就是因為pipeline統一維護困難,且沒有層級劃分。jenkins在面向企業級方面還需要提供更豐富的功能。

每日構建次數:每日構建次數包括所有環境的發布次數,平均每日大概在1500次左右。

圖18 每日構建次數

每日上線次數:每次上線次數為項目發布到生產環境的次數,平均每日大概100次左右,同時支持hotfix發布,隨時回滾等。

圖19 每日上線次數

3、組件庫

因為我們開發語言的原因,所以不同開發語言有對應的組件倉庫,這在前面的發布API裡面已經講過,主要是java的nexus倉庫、php的ppkg倉庫、nodejs的npm倉庫,這裡就不重複了

4、製品庫

製品庫分兩種,虛擬機和docker發布,其中虛擬機發布的我們直接將編譯構建好的內容保存起來,供推送其他環境時可直接使用,達到一次構建,處處運行的目的(和環境有關的配置統一放在配置中心,每次發布前通過校驗類流水線任務,校驗完成配置後方可發布);

docker的是直接構建成鏡像,上傳到harbor鏡像倉庫,在觸發kubernets容器集群啟動容器時從鏡像倉庫獲取鏡像啟動。

5、虛擬機發布

虛擬機發布是使用rsync服務進行文件同步,將代碼從製品庫同步到對應伺服器,然後伺服器上有一個守護進程,會實時監測文件是否更新,若有代碼更新則進行重啟操作;

圖20 發布流水線之 虛擬機發布

6、docker發布

docker發布是調用kubernets進行發布,將事先生成好的yml文件傳遞給kubernets,然後在對應數據中心啟動容器,並通過zbjcheck服務校驗功能確保服務啟動正常後,再刪除老的容器,達到不停機升級的目的。

7、自動化測試

目前DevOps集成了單元測試(包括自動生成單元測試用例)、介面測試、性能測試的功能。單元測試大部分情況下還是需要開發人員寫用例,自動生成單元測試用例的功能並不是那麼好用,所以用戶較少,但在流水線上會自動進行單元測試,並將結果反饋給用戶:

圖21 自動化測試之 單元測試

單測結果是基於sonar的,在jenkins上執行完單測後連同靜態檢測結果一起發布到sonar,在sonar上配置了通用的過濾條件,可以過濾掉部分不需要統計單測的代碼(如框架自動生成的代碼不計入單測覆蓋率),用戶可以在此基礎上配置其他過濾條件。

介面測試和性能測試方面,我們在DevOps平台上做了一個關聯的功能,每一個介面測試或者性能測試用例,都對應一個項目工程,關聯關係梳理好後可以實現在發布流水線的任意環節觸發介面測試或者性能測試。

和項目工程關聯:

圖22 自動化測試之 介面測試

發布流水線觸發介面測試:

圖23 介面測試與流水線集成

發布流水線觸發性能測試:

圖24 性能測試與流水線集成

自動化測試的結果展示方面目前做的不夠好,只是在日誌中提供鏈接,用戶點擊鏈接進去查看結果。

8、CMDB

CMDB作為底層的統一資源管理中心,負責跨數據中心的混合雲管理,提供統一的資源管理平台,不管私有雲還是公有雲,不管虛擬機還是docker都統一管理,同時提供對底層服務的訪問支持。提供機器與宿主機的拓補圖關係等,對基礎設施的管理提供了便利。

圖24 CMDB功能架構圖

一套openstack表示一個虛擬化集群,一套kubernets表示一個容器雲集群,每個數據中心有一套或多套openstack和kubernets。CMDB通過數據中心和可用區來標示不同的集群。任何需要和虛擬機和容器對接的功能統一由CMDB提供介面管理。

9、DNS解析

DNS作為附加的功能,可由用戶直接點擊一個按鈕實現域名解析:

圖25 域名解析示意圖

域名解析是一個比較複雜的過程,它需要和後台很多系統交互,還需要根據事先定義好的nginx模版生成配置,docker的服務還需要進行動態服務發現,最終將域名信息註冊到DNS中。

10、擴縮容

DevOps平台同時支持對虛擬機和docker的擴縮容功能,只要對應數據中心存在對應的服務,就可以進行擴縮容,一次擴容節點不能超過10個,縮容節點數最少保留一個

圖26 彈性擴縮容功能圖

我們能對不同數據中心的服務進行擴縮容,並且所有的操作都有事件機制,能將每個服務所使用的資源進行歸檔管理,最終可以對各個部門所使用的資源進行伺服器成本費用結算。

11、控制台

從瀏覽器進入伺服器,且通過許可權控制,有許可權人員才能進入,更加方便排查問題:

圖27 進入控制台界面圖

圖28 進入控制台界面圖

12、監控

DevOps已經集成了監控的部分功能,包括介面調用情況、全站可用性、監控數據排行榜、金絲雀分析等

1)可用性監控

圖29 網站全局可用性監控圖

圖30 網站分類可用性監控圖

圖31 網站可用性詳情

2)監控數據排行榜

圖32 服務監控排行榜

圖33 介面級服務監控

圖34 介面級服務監控

3)介面調用情況

圖35 介面級服務調用監控

圖36 介面級服務響應

4)金絲雀分析

金絲雀分析主要用於在代碼發布到灰度環境時,分析灰度環境和線上環境的相關指標值對比,以確保新版本代碼質量不必老版本差

圖37 金絲雀分析功能圖

目前只有以下幾個指標數據,後續將不斷完善指標內容:

圖38 金絲雀分析結果圖

灰度環境和線上環境都承擔用戶流量,通過nginx的upstream進行權重設置,我們可以根據金絲雀結果做一次上線發布前的質量評估。

三、未完待續

雖然我們完成了DevOps的大部分功能,要講到技術細節,上面的每一個小節都能用一篇文章來講解,所以以後我們會不斷分享我們在DevOps中的一些技術細節,當然我們也還有很多需要優化和改進的。需求搜集和規劃、項目管理和發布關聯、自動化測試、金絲雀分析的改進、自助作業平台、CMDB對混合雲的管理等都是後續需要改進的,整體的規劃圖如下:

圖39 DevOps平台功能架構分布

DevOps平台功能架構分布中,還有很多工具以及功能未描述,上面講到的每一個點都可以展開為一篇文章做詳細介紹,這裡主要為2017年做一個總結。

以上內容為豬八戒網最近幾年來整個DevOps的發展演進史,公司的規模不同,整體架構以及方法可能不同,對於豬八戒來說,DevOps還在繼續演進,同時也會不斷學習業界優秀實踐,為業務發展提供最基礎的保障。


推薦閱讀:

CI Weekly #10 | 2017 DevOps 趨勢預測
2018年即將要自動化的5件事
【乾貨合集】阿里雲專家詮釋持續集成與雲端交付的正確姿勢:在雲上如何歡快的用好容器服務?
微服務架構下的開發部署實踐(1)

TAG:DevOps |