當前位置:
首頁 > 科技 > 攜程網是如何做好持續交付的?

攜程網是如何做好持續交付的?

作者 | 王瀟俊

出處 | 極客時間《持續交付 36 講》專欄

隨著雲計算、容器等新興技術的發展,「持續交付」這個老生常談的問題,忽如一夜春風來,彷彿找到了從理想通向現實的大門。各類相關工具、產品、服務,也是紛紛出現:如 Jenkins 2.0,Jenkins X,阿里雲效,Netflix Spinnaker,Jfrog Artifactory 等等。

我是王瀟俊,攜程網系統研發總監, 接下來,我會結合在攜程網工作的真實案例,分享關於持續支付的一些想法和經驗。

1

什麼是持續交付?

首先我們要搞清楚什麼是持續交付,其實這就好像你去問 100 個哲學家,「哲學」的定義是什麼,你會獲得 101 個答案一樣。與馬丁 · 福勒(Martin Fowler)老爺子在 2006 年,提出「持續集成」概念時一樣,我們可以把「持續交付」定義為「一套軟體工程方法論和許許多多的最佳實踐的集合」。

持續交付也通常以「發布流水線」的方式來解釋,即研發團隊從開發,到測試,再到部署,最終將產品交付給最終用戶使用的過程。如下圖:

持續交付它所要達到的目標是在「最終用戶」和「研發團隊」之間建立緊密的反饋環:通過持續交付新的軟體版本,以驗證新想法和軟體改動的正確性,並衡量這些改動對軟體價值的影響。這裡說的「軟體價值」,說白了就是收入、日活、GMV 等 KPI 指標了。

2

持續交付能力——研發能力的重要指標

在互聯網應用盛行、速度為王的今天,持續交付的價值被突顯出來。持續交付的能力,正成為評定一家互聯網公司研發能力的重要指標。無論是什麼企業,無論你的職位高低,作為不同的角色、站在不同的角度,都可以或者應該去嘗試持續交付,它一定會讓你覺得物超所值。

如果你是 CTO 或者是一個較大規模研發團隊的管理者

你是不是時常困擾於技術選型的問題?

你是不是經常頭痛於已制定的標準難以落地?

你是不是時常考慮如何提高跨部門協作的效率?

你是不是擔心「黑天鵝」的降臨?

如果你是 Team Leader

你一定希望團隊的知識能夠傳承。

你一定希望團隊專註於業務而非工程。

你一定希望以一個較平穩的節奏持續工作。

如果你是產品經理

你應該是產品真正的第一個用戶。

你應該完全知悉當前的進度和質量。

你的產品應該隨時能發布。

如果你是一個程序員

你可以通過對持續交付的學習,進一步加強自己對整個軟體工程的認識。

你可以利用持續交付的工具或最佳實踐,提高自己的工作效率和質量。

你可以參與到持續交付實施中去,享受為其他程序員提供效率工具的挑戰和樂趣。

掃碼試看或訂閱專欄

3

攜程網如何做好持續交付的?

在我開設的技術專欄《持續交付 36 講》完結之際,整理了大家的留言,總結了比較典型的 5 個問題,針對這 5 個問題再詳細展開,分享一些攜程在這些方面的真實方案和實踐:

測試環境使用和管理的實例;

怎麼處理資料庫發布和回滾;

Immutable,在攜程是如何落地的;

攜程的破壞性測試,DR 演練;

攜程 GitLab HA 方案。

第一個問題:測試環境使用和管理的實例

攜程的測試環境包括這麼三類:

FAT 環境,為每個團隊或功能準備的獨立功能測試環境;

FWS 環境,部署穩定版本的功能服務,以供其他團隊聯調的環境;

UAT 環境,用戶接受測試的環境,包括獨立部署的 DB、緩存和中間件。

這三類環境中,UAT 環境的使用和管理方法大家都已經比較熟悉了,所以這裡我再著重和你分享一下 FAT 和 FWS 環境相關的內容。

我在這裡放置了一張圖片,用於展示 FAT 和 FWS 環境的關係,

圖 1 FAT 和 FWS 環境的關係

FAT 與 FWS 環境的關係

FAT 環境屬於不同部門,可以包括多套環境。在管理時既可以按需臨時生成,也可以作為常備環境持久保留。我們可以在一套 FAT 環境中,部署任意個服務應用。

而 FWS 環境主要部署的是中間件和公共服務,通常情況下它的版本與生產版本一致。

FWS 和 FAT 這兩類環境,在網路上完全相同,並共用一組資料庫和緩存。

如何控制服務調用關係?

既然 FWS 和 FAT 這兩類環境完全相同,而且不同的 FAT 環境中也會存在相同的服務應用,那麼我們就必然要解決一個問題,即:如何控制服務的調用關係。

因為即使是相同的服務應用,部署在不同的 FAT 環境中的應用版本號也可能不一樣。如果按照標準服務治理方式的話,那麼就需要把所有 FAT 環境中的同一個服務認為是一個服務集群。而同一應用的不同版本同時服務的話,它們提供的功能也不一樣,這會對測試產生負面影響,因為無法確定出現 Bug 的版本到底是哪一個。

那麼,攜程是如何解決這個問題的呢?

攜程的解決方案是,由 SOA 通信中間件指定服務的具體地址,即通過配置指定要調用的服務的具體地址。當然,如果每個服務都要去指定配置,那麼就太過繁瑣了。所以,我們還定義了一條默認規則:

如果沒有特別指定的服務調用地址,則優先調用同一個環境中的相關服務。如果同一個環境中該服務不存在,則嘗試調用 FWS 中部署的實例。

在攜程如何創建測試環境?

在攜程,我們有一套完整的測試環境自助管理平台,開發人員或 QA 團隊可以按需自助完成對對測試環境的任意操作。這裡,我也分享一下,在攜程創建一個測試環境的大致步驟。

第一步,選擇一個已經存在的 FAT 環境,或者重新創建一個 FAT 環境。如果是重新創建的話,可以選擇重新創建一個空的環境,或者是複製一個已有的環境。

第二步,選擇要在這個 FAT 環境下部署的服務應用,先進行關係綁定(即,這個 FAT 環境下要部署的所有服務應用的描述)再部署。如果該服務屬於其他團隊,則可以要求該團隊協助部署(由平台來處理)。在攜程,一個團隊只能部署屬於自己的服務應用,如果你的 FAT 環境中包含了其他團隊的應用,則要由其他團隊部署。這樣做的好處是各司其職,能更好地控制聯調版本。

第三步,配置這個 FAT 環境相關的信息。攜程的配置中心,同樣也支持多測試環境的功能,可以做到同一個配置 key 在不同環境有不同的 value。

第四步,對於特殊的服務調用,進行單獨配置。

經過這樣的四步,一個測試環境就被創建起來了。期間測試環境的任何變化,都可以通過環境管理平台完成。比如,增減服務應用、修改配置,或是擴容 / 縮容伺服器等。

第二個問題:如何處理資料庫發布和回滾?

這也是一個大家比較關心的問題。我來和你分享一下攜程的實踐吧。

在攜程,資料庫的變更是和應用發布拆分開的。也就是說,我們的資料庫有單獨的持續交付流程。這個持續交付的過程大致如圖 2 所示。

圖 2 資料庫持續交付

在這個過程中,有兩處 DBA 審核:

第一處審核,是在提交腳本之後。審核的內容主要是變更內容是否合法、方式是否得當、是否影響業務等等。

第二處審核,是在提交生產變更後。審核的主要的內容是,判斷變更是否會對當時的生產系統產生影響。比如,訂單表的更新、大表的變化等,就不允許在業務高峰期進行。

整個資料庫發布的持續交付流程,是以測試通過為驅動的。這個過程,要經歷開發、功能,以及集成測試 3 個環境。而資料庫的發布又與代碼發布不同步,所以如果有兼容問題的話,就容易被發現了。

那麼,怎麼做到兼容呢?攜程對資料庫變更的要求是:

第一,與業務相關的,只能新增欄位,不能刪除欄位,也不能修改已有欄位的定義,並且新增欄位必須有默認值。

第二,對於必須要修改原有資料庫結構的場景,則必須由 DBA 操作,不納入持續交付流程。

所以,按照這個管理方式處理資料庫的持續交付的話,資料庫本身基本就沒有需要回滾的場景了。

第三個問題:Immutable,在攜程是如何落地的?

我之前提到過「不可變」的概念和價值,也講到了任何系統的變更都要視為一次發布。然而,在傳統的基於虛擬機的系統架構下,要做到這一點代價非常大。

所以,攜程基於 Docker 容器和 k8s 落地了不可變模型。

具體的實現思路,其實也很簡單。在落地不可變模型之前,我們只有應用發布,這一個可追溯的版本樹;那麼,針對不可變的需求,我們在其上增加了一個系統變更版本樹。同樣地,原來只在代碼交付時才會進行鏡像和部署;現在在系統變更時,我們也會針對性地生成鏡像、標註版本、進行部署。

將應用發布和系統變更這兩條版本樹合併,就是完整的不可變模型需要的版本樹了,也就是落地了不可變模型。

第四個問題:攜程的破壞性測試:DR 演練

其實,攜程的破壞性測試也只是剛剛起步,還沒有完全具備混沌工程的能力,其原因主要是:很多的老舊系統比較脆弱,不具備在所有的隨機破壞後快速恢復的能力。

但是,攜程在同城多機房 DR(災難恢復)方面,做得還是比較出色的。其實,DR 演練也是一種破壞性測試,一般採用的方式是局部斷電或者流量切換。所以,我們也會定時做 DR 演練,以檢驗系統健壯性是否達標。

其實,破壞性測試和 DR 演練這兩種方式的最終結果是一樣的,都是將所有生產流量從災難機房遷移至其他正常機房。當然,要完成這樣的切換,同時不影響正常業務,我們需要在架構層面多花費一些精力。比如,資料庫的同步、Redis 的同步、SLB 路由的快速切換,等等。

我們一起看一下 DR 演練的具體過程吧。假設 IDC B 的某個服務單元出現了異常,如圖 3 所示。

圖 3 個別服務單元故障

而此時,IDC A 有這個服務單元的災備存在,那麼系統就會被觸發流量切換,即:GLB 會將所有發給故障服務單元 SLB 上的流量,切換到 IDC A 的災備服務單元上,如圖 4 所示。

圖 4 流量切換後

這樣,故障的服務單元就暫停了服務,直接由災備服務頂上了。

當然,這種演練不僅僅是整個服務單元異常這一種場景,還可用於單元內的個別服務的異常演練,這時的流量切換就不再是由 GLB 這種上層來做了,而是利用 SLB 這一層的能力,切換部分服務的流量到災備服務上。

最後,你還要記住的很重要的一點就是,要能探測到故障單元是否恢復正常了。如果恢復正常了的話,流量還要還原回去。這部分的能力,可以利用 SLB 的健康檢測實現。

其實,整個 DR 演練過程中最容易出現問題的是,資料庫和緩存的處理。如果沒有跨機房數據實時同步的能力,建議最好不要嘗試,畢竟不要把演練變成了破壞。

第五個問題:攜程的 GitLab HA 方案

攜程的 GitLab HA 方案,主要是基於 Sharding 思想,大致的架構設計如圖 5 所示。

圖 5 攜程 GitLab HA 方案

這個方案的核心思想是:通過 Nodejs ssh2 代理和分發所有 SSH 請求,利用 Nginx 代理和分發所有 http 請求。具體的實施,包括以下三點:

第一,每台宿主機上有多個 GitLab 實例,可以是虛擬機形式,當然也可以是容器形式。

第二,同台宿主機上的 GitLab 實例共享一個 Volume,這樣就保證了即使某一個 GitLab 實例故障,也可以快速將流量切換到同宿主機的其他實例上,繼續提供服務。

第三,我們對每台宿主機的倉庫,簡單地用 rsync 做了冷備。此處並沒做互備,否則就變成 NFS 方案了(因為,我們的目的是,只要保證存儲故障時可恢復,所以無需採用 NFS 方案)。

這個方案的開發成本和維護成本都比較小、簡單實用,你也可以借鑒。

持續交付的價值不僅僅局限於簡單地提高產品交付的效率,它還通過統一標準、規範流程、工具化、自動化等等方式,影響著整個研發生命周期。

持續交付最終的使命是打破一切影響研發的「阻礙牆」,為軟體研發工作本身賦能。無論你是持續交付的老朋友還是新朋友,無論你在公司擔任管理工作還是普通的研發人員,持續交付都會對你的工作產生積極的作用。

如果你想系統的學習持續交付,可以通過極客時間訂閱我的專欄《持續交付 36 講》。現在訂閱還有福利。

4

限時 24 小時福利

極客時間《持續交付 36 講》專欄圍繞持續交付知識詳解、持續交付的平台化、打造移動 App 的持續交付體系、利用開源工具快速打造持續交付平台,共 4 大模塊 36 講展開分享,量身定製你的持續交付體系。

希望通過專欄的學習,你和你的團隊可以在保證交付質量的前提下,加快交付速度,從而更快地得到市場反饋,引領產品的方向,最終達到擴大收益的目的。現在訂閱,有以下福利:

福利一:今天限時拼團優惠價 49 元 /2 人,原價 68 元 /36 講,10 月 29 日恢復原價。

福利二:每邀請一位好友購買,你可以獲得 18 元現金返現,多邀多得,上不封頂,隨時返現。(提現流程:極客時間 APP- 我的 - 分享有賞)


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

GitHub發布史上最大更新,年度報告出爐!
Eric Evans:DDD還未結束!

TAG:InfoQ |