雲縱持續交付環境管理進化歷程
破天(李進莊)、冬草(宋玥輝) 創作於2018-9-10
一個公司的運維能力強弱和你線上環境敲命令是有關的,
你越是喜歡上線敲命令,你的運維能力就越弱,
越是通過自動化來處理問題,你的運維能力就越強。
——陳皓,2017
持續整合(Continuous Integration, CI)是一種軟體開發實踐,即團隊開發成員經常整合他們的工作,通過每個成員每天至少整合一次,也就意味著每天可能會發生多次整合。每次整合都通過自動化的構建(包括編譯、釋出、自動化測試)來驗證,從而儘早地發現整合錯誤。
持續部署(Continuous Deployment, CD)是通過自動化的構建、測試和部署,迴圈快速交付高質量的產品。某種程度上代表了一個開發團隊工程化的程度,畢竟快速運轉的網際網路公司人力成本會高於機器,投資於機器優化開發流程也提高了人效。
上述資料均說明了環境管理自動化對於網際網路公司的重要性。
Docker自2014年以來非常火熱,隨著容器化的如日中天,另一個理念DevOps也在不斷傳播。大部分IT從業者對於DevOps本身也都有一定的瞭解和認識,然而企業內部要想根據DevOps思想實踐一條自己的路,絕對不是一件簡單的事。而我司自2014年11月份開始引入容器到現在為止,一直在DevOps的路上不斷地探索中,在這期間業界也沒有出現一套標準的開源工具集可以借鑑,因此我們只能摸著石頭過河。以下為我司的一些經驗分享。
我司的環境演化史

2014年11月份在容器化啟動之前,我司的開發、測試及線上環境都是部署在基於OpenStack的虛擬化伺服器上,技術團隊需要維護的環境劃分得很細:開發環境、測試環境、特殊測試環境、緊急測試環境、映象環境、線上環境。
2015年9月隨著容器化技術的使用以及雲縱業務調整,環境管理縮減到了四個。
到了2016年3月,我司啟動了CloudEngine的開發,一個基於私有云的研發協作系統。基於CloudEngine,我司初步實現了DevOps的雛形。在之後,根據業務需求,我們先後實現私有云灰度釋出功能、多機房混合雲多活管理功能。
基於CloudEngine的基礎環境管理架構如下圖所示,CloudEngine架設在TouchStone(容器化管理平臺)、SimpleWay(運維自動化平臺)、iDB(資料庫自動化運維平臺)、Jenkins(注:開源產品)等基礎設施系統之上,可以看作是一個元資料管理者和流程排程的發起者,同時支援虛擬機器和容器資源申請等,等同於我們的私有云管理系統+專案需求開發測試跟蹤系統的結合體。

環境演化推動過程
CloudEngine引入背景
在CloudEngine引入之前,開發使用開發聯調環境,測試使用測試環境,此時我們最大的痛點是多需求併發開發,或多需求併發測試,這個時候我們只有兩個解決方案:
- 多準備幾個開發聯調環境和測試環境(這也是容器化之前維護很多環境的原因之一),每個需求版本使用自己單獨的環境,但是環境維護困難,開發人員排查起來問題也困難。
- 程式碼變更要求向上相容,但是向上相容有時候是比較困難的,甚至有時候只能序列。
為了解決快速部署一套開發聯調環境或者測試環境,我們很早就引入了容器化技術,但是即使通過容器化技術,環境維護也是比較困難的。
CloudEngine1.0實現CI/CD流水線管理
機緣巧合之下我們接觸並深入瞭解了螞蟻金服的研發協作平臺,我們把龐大的螞蟻金服研發支撐體系濃縮為四個平臺:ACP(阿里協作平臺)、九州資源管控平臺、AQC(螞蟻質量基礎設施平臺)、Zpass(螞蟻集團釋出部署平臺)。ACP是總驅動,九州、AQC、Zpass作為基礎設施,整個形成一套CI/CD流水線。

而此時,我司的持續整合體系如下:
專案管理、測試用例、缺陷管理我們有一套管理體系;
自動化編譯、自動化部署、自動化測試我們有一套管理體系;
映象管理、應用釋出、應用監測我們有一套管理體系;
容器管理、叢集管理我們也有一套管理體系。

我們發現私有云體系的基礎系統我們已經基本具備,現在需要一個PAAS平臺來把研發從環境申請到測試釋出上線整個研發測試鏈路管理起來,因此我們(注:牽頭人是田志全)提出了CloudEngine(下面簡稱CE)的建設解決方案,功能點如下:

CE機器申請:當一個需求從提出進入研發階段後,研發經理在CE中選擇應用、環境、虛擬化方案、Git地址等資訊就可以做到一鍵完成機器申請、編譯構建、環境部署和環境監控。研發在Git開發分支上進行編碼開發,當開發到一定階段隨時可以在服務申請列表中找到申請的機器進行重新部署,以達到CI(持續整合)的目的。

CE提測申請:當研發開發聯調完成後,研發經理在CE中可以直接建立提測單,CE把多個應用打包到一起進行提測。測試人員直接使用研發申請的環境進行測試(不會建立新的測試環境)。

CE上線釋出:當測試人員測試通過之後,測試經理在CE中可以直接建立上線工單,CE呼叫SimpleWay直接會把之前環境的的Docker映象推送到線上環境(一包通用),如阿里雲,如自建IDC機房,以達到CD(持續部署)的目的。

在整個CI/CD流水線管理中涉及兩個核心技術點要解決:
- 引入Stable環境概念
日常開發申請機器時,通常只需申請有程式碼變更的應用機器,所依賴的其他應用均來自於Stable環境。如下圖所示,當我們訂單服務有程式碼變更的時候,只需要申請一個Dev環境訂單服務機器即可,購物車和支付服務還使用Stable環境的機器,即系統呼叫鏈路要能判斷出是否有非Stable環境的應用,沒有的話才會呼叫Stable環境應用。

我司應用之間的呼叫基本上使用Dubbo的RPC呼叫(而不是微服務的RestFull API,改造成本低一些),我們的解決方案是在容器申請時的ENV中打入環境標示,比如開發Stable環境標示為:SYS_ENV=ds,開發dev環境標示為:SYS_ENV=d,Dubbo在做服務呼叫時,優先選擇非Stable環境的機器。
另外一個考慮點是MQ,我司使用的是自建Notify MQ,我們的Notify是按QueueName進行訊息分組的,解決方案是不同的環境建立不同的QueueName即可,無需程式碼改造。
- 一包通用解決方案
一包通用指測試和線上使用相同的映象包,技術難點在於配置資訊可根據不同環境自動拉取配置。這樣做的好處是測試人員測試的結果能真實反映到線上環境,避免上線重新編譯打包引起的各種不一致問題(之前我們經常遇到上線分支合併出現問題影響到了線上環境)。
我們的解決方案是使用Diamond分散式配置管理統一管理各個應用各個環境的配置資訊,各個應用的映象在啟動的時候根據dockerfile和tpl.properties(應用配置模版)從Diamond中拉取自己的配置資訊,寫入app.properties(應用真實配置檔案),之後再進行容器啟動以適配具體環境。具體流程如下。

CloudEngine2.0實現灰度釋出管理
2017年開始隨著我司業務擴張,每週都有三到四次大的上線操作,為了不影響線上使用者體驗,每次上線都要求在0點之後進行,上線完成之後,測試人員要通跑一遍業務流程,隨著業務不斷的複雜化,每次上線都要求相關測試和研發進行一次通宵,有些時候遇到上線失敗回滾,還有可能通宵兩次。為了解決這個痛點,我司根據自己的私有云管理情況提出了一套灰度釋出解決方案。

灰度解決方案主要支援流量比例規則和指定IP規則。外網第一層Nginx的Lua指令碼根據灰度規則組配置進行請求流量篩選,符合灰度條件的請求會在header中打入灰度標示並轉發到灰度Nginx,從這裡開始環境進行了隔離,但是到了後臺服務端因為有環境重合的可能,所以我們利用ThreadLocal實現了一套灰度上下文,Dubbo做服務分發呼叫的時候,根據灰度上下文中的標示做判斷進行灰度環境呼叫,整個請求處理流程如上圖所示。
這裡我們也想過完全的環境隔離方案,即灰度單獨使用一整套自己的環境,但是我們分析灰度的業務也是線上業務,我們的訴求是請求隨時可以進入灰度,隨時也可以退出灰度,所以灰度庫和線上庫應該是一套資料庫,另外上線灰度環境的應用可能是任何一個或多個應用,所以最終我們選擇了侵入性比較高的強控制方案。
CE3.0+SimpleWay2.0實現跨機房多活
2018年年初開始,隨著我司業務繼續擴張,尤其支付業務的重要性越來越高,本年3月份我司正式提出啟動異地多活專案,著重解決雙機房切換問題。
異地多活的實現目標:
- 雙機房同時提供服務,流量按照指定規則打到不同機房;
- 當機房A發生災難時,能將流量全部切換到機房B且不會壓垮機房B的既有服務;
- 機房之間資料雙向同步,資料同步在2秒內完成。不同機房短時間內不對同一行資料進行寫操作;
異地多活的技術難點主要在資料跨機房同步和流量請求控制兩方面,經過多次討論分析我們最終確定的解決方案如下:

- 每個機房配備有一個管控系統、兩套業務分片、一份全量SQL/">MySQL節點,分片之間的應用是完全的網路隔離。
- 流量按商戶ID進行規則分流,不同商戶分流到不同機房。
- 每個機房有一個主分片和一個輔分片,主分片主要承接分到這個機房的流量,輔分片是另一個機房主分片的備用分片,當另一個機房掛掉,流程切到這個機房的輔分片上,主分片的業務不受影響。
- 資料庫獨立於分片之外,每個機房一套完整的資料庫,採用Otter服務實現雙向資料同步。
跨機房資料同步需要注意的點:
跨機房同步型別主要有三種:不同步、單向同步、雙向同步。其中不同步不必考慮,需要考慮的只有單向和雙向兩種:

業務系統改造點(注意點)

其他補充點
多活解決方案的目標主要是做機房容災,即當A機房發生不可抗拒災難後,我們可以快速把流量切到B機房以減少災難造成的影響,以目前我們的解決方案,在災難發生的一瞬間,資料雙機房備份如果沒有同步完成也會有一些細微的影響,目前只能人工干預,在災難結束後人工對受影響的資料進行訂正。
未來的進化方向
息壤(質量管理)
2018年已進入下半場,為了繼續提升我司的生產效率,保證我司工程釋出質量和合規性,同時考慮我司私有云等各種雲的操作複雜性,降低學習成本和犯錯機率,需要繼續完善我司的大研發協作平臺,對標螞蟻的AQC(質量基礎設施平臺),我司在質量自動化管控方面還存在一定短板,因此後續我們考慮構建我們自己的質量協作平臺“息壤”,將CloudEngine、RAP、JMeter等流程串接起來實現質量管控的自動化管理。
取名息壤的意思是:這是一塊能自己生長的土壤,元資料(如介面定義)錄入後,隨著產品迭代,它能自己慢慢生長,自動化單元測試,測試用例自動化執行,場景自動迴歸,日檢等等。

總結
雲縱是一個篤信工程師文化的公司,我們崇尚依靠技術(及自動化)而不是依靠線下流程(注:為了避免網友誤會,此流程特指線下人工流程)和管理解決問題。
我們的體系架構巨集大,我們持續投入資源(注:日常20%~30%的研發資源),雖然此體系絕非一朝一夕所能完成,但是我們秉承 平凡人可做非凡事 和 日拱一卒功不唐捐 的理念,一群信仰技術的工程師邊開飛機邊換引擎,我們終會有實現巨集偉藍圖的那一天。
參考資源:
1,2018,#研發解決方案#異地多活讓商戶無感知;
2,2017, ofollow,noindex" target="_blank">輕舟已過萬重山——真正的技術派公司是怎麼聯調、測試和釋出的? ;
3,2016,私有云的難處—為什麼需要CloudEngine?;
4,2016,#研發解決方案#研發協作平臺CloudEngine;
-EOF-
/* 敬請關注我的公眾號:老兵筆記* /