1. 背景
測試環境治理一直是各大公司非常重要的一個課題,測試環境穩定性很大程度影響迭代開發&測試效率。
綜合來看,測試環境不穩定的原因主要有以下幾點:
- 測試環境的變更非終態變更,經常會有程式碼釋出/配置釋出導致服務無法啟動或者鏈路有問題的情況。
- 變更頻繁,開發需要聯調、測試需要迭代測試,程式碼需要變更,配置也需要變更,許可權控制就比較難做,增加了測試環境不穩定性。
- 並行需求,同一時間單個應用需要多個分支同時支援多個需求的測試,測試環境資源的搶佔和衝突比較明顯。
得物測試環境穩定性治理也經歷了幾個階段:
2020~2021:多套物理環境隔離方案(基於ECS)
T0、T1、T2三套測試環境,每套環境物理隔離,無資源衝突和共享。
規劃T1用於迭代測試、T0用於整合迴歸、T2用於獨立專案分配使用,但在實際使用過程中,業務測試並行太多,衝突比較明顯,環境就開始亂用了,誰有需求就隨便佔用一套環境使用了。結果就是沒有一套穩定的環境,測試有效性無法保障,並行專案環境衝突也無法解決。
2021~2022:MF全鏈路容器環境方案(基於容器)
隨著業務增長,3套測試環境已明顯不能滿足業務需求,因此去年得物基於容器快速搭建了10套MF環境用於支撐獨立專案的測試。
MF環境基於T0搭建,DB和T0共享,其他所有資源均獨立,目的是做到業務只需保障T0的穩定性,所有MF環境可快速基於T0同步最新服務和最新配置,做到環境隨用隨取,解決並行專案環境衝突問題。
實際實施過程中,專案環境衝突的問題解決了,但是MF環境的穩定性問題依舊比較嚴重,維護成本巨大,主要原因集中在:
T0環境穩定性,並非所有域都在T0整合迴歸,導致T0穩定性無法保障
MF同步了T0之後會因為各種各樣的原因需要二次除錯驗收(新增服務丟失、配置不全/錯亂等)
MF環境使用過程中,基礎服務(sso、閘道器、中介軟體)等相關變更無法及時更新到MF環境,影響業務測試
因此在2022年下半年,開始嘗試用染色環境解決環境穩定性問題。
2022年:染色環境方案(基於流量隔離)
染色環境是基於流量隔離的方案,透過流量標透傳的方式,把基準環境流量和染色環境流量隔離開,實現多環境的方案,支援並行測試互不影響。
相較於MF環境而言,不需要維護多套全鏈路環境,維護成本降低了。所有變更的服務都在染色環境部署的話,基準環境穩定性就會提升,相當於所有環境的穩定性都提升了。
下面主要介紹得物染色環境是如何做的
2.染色環境方案
2.1 基本思路
如下圖所示,最初的設想是:
- 服務可以按照流量標把流量路由到相應染色服務上
- 如果染色標對應染色環境沒有此服務,則流量會走到基準環境
- 如果染色環境服務新增了,沒有部署,或者部署了服務程式掛了,則流量會報錯而並非走到基準環境(避免一些服務異常問題沒有暴露)
- DB、MQ、Redis等中介軟體期望用同一套,避免浪費
基於此設想,需要從哪些地方入手去改造以支援染色環境呢?可以從設想拆解去解決:
- 流量標如何透傳?
- 流量路由如何路由到染色節點?
- rpc介面如何路由到染色節點?
- MQ訊息如何讓染色環境consumer消費?
- 解決完流量標透傳問題,以及染色路由問題後,需要考慮流量發起方如何把染色標帶上?
2.2 實現方案
以下方案只做流量隔離,DB資料層不做隔離
1.流量標如何透傳?
首先流量標在流量入口層會放到http header裡面的x-infr-flowtype欄位:
x-infr-flowtype:<CE_ColoringEnv> ##CE_是固定字首,為了和壓測標做區分
從流量到閘道器後,服務鏈路上面流量標往下透傳的方式是透過OpenTracing規範中的baggage能力,從header裡面獲取染色標,並塞到trace裡面向下透傳。
這樣整個鏈路裡面就都能拿到染色標了
2.流量路由如何路由到染色節點?
這裡分兩塊考慮:
(1)rpc呼叫,拿到染色標之後,如何找到染色節點?這裡要解決的是怎麼識別染色節點
(2)MQ訊息,producer如何傳送帶染色標的訊息,consumer如何處理帶染色標的訊息
服務註冊--識別染色節點
- 首先染色環境建立的時候,會定義好染色標:
在此染色環境新增服務部署的時候,預設會把染色標註入到環境變數COLORING_ENV
容器釋出配置頁面會自動增加COLORING_ENV變數
至此,服務啟動時已可以讀到COLORING_ENV環境標變數了,下一步就看註冊中心怎麼去區分染色節點了.
首先服務在新增到染色環境的時候,服務會在註冊中心染色場增加一個節點,標明該服務在此染色環境是有服務節點存在的。
染色場主要解決的問題是:如果染色節點掛了,染色環境流量應該判斷該染色環境是否應該有染色節點,有的話就報錯,沒有的話才會走到基準環境。避免測試問題未暴露。
染色場:CE_< ServiceName>
染色場服務節點:<COLORING_ENV>:80
其次在服務註冊時候,服務節點資訊和方法註冊會攜帶染色標<coloring_env>:
至此,註冊中心就可以基於染色標識別染色節點,業務服務(基於fusion框架)可以根據Trace中的染色標結合註冊中心染色節點做染色流量路由。
- MQ改造--識別和處理MQ訊息
MQ主要解決的是,染色環境的訊息生產者producer傳送的訊息,只被染色環境的消費者消費,染色環境如果沒有消費節點,則由基準環境消費者消費。
這裡之前討論了兩種做法:
第一種是基於Topic隔離的方案,每套染色環境使用不同的topic進行通訊,這樣隔離性比較好,訊息不容易串掉。
第二種是Topic不隔離,所有染色環境共用一個topic,生產者Producer在生產訊息時候把染色標帶上,consumer每套染色環境有一個,consumer在做消費時候會判斷訊息裡面的染色標和本地染色標是否一致,如果一致則消費,如果不一致則直接返回ACK不走具體消費邏輯。
目前選擇的是第二種方案,下面基於第二種方案做詳細介紹:
基本流程
如圖所示:
- ServiceB_Color1會自動註冊GID_Color1_Topic消費組,監聽Topic_A。Color2和Color3環境一樣。
- 帶Color1的訊息由ServiceA_Color1生產,ServiceB_Color1消費。
- 帶Color2的訊息由ServiceA_Color2生產,ServiceB消費,因為ServiceB在Color2染色環境沒有節點
- 帶Color3的訊息由於染色環境Color3沒有ServiceA_Color3節點,則帶Color3的流量會打到基準環境ServiceA,此時ServiceA會生產帶Color3的訊息,此訊息由ServiceB_Color3消費
配合業務說明:
染色環境在啟動時候,帶染色標的GID會自動建立,eg:原GID是GID_AAA,染色自動建立的GID為GID_<coloring_env>_AAA
下面看訊息的內容和處理邏輯:
如上圖:染色訊息屬性裡面會增加DMQ_ENV_TAG欄位,新增染色標,然後對應染色環境訂閱組才會消費。
看上面這張圖,會發現“貌似”所有染色環境都消費了,其實是其他環境直接返回了ACK,未走具體的消費邏輯,具體可以看日誌。
程式碼說明:基於Message裡面染色標msgTag和本地服務染色標envTag進行判斷做消費邏輯區分。
3.染色流量入口攜帶染色標
解決完染色標透傳,以及染色標邏輯處理後,剩下就是如何在流量發起方把染色標給帶上了,其實就是把染色標塞到header裡面的x-infr-flowtype欄位。
其中染色環境列表的獲取由釋出平臺提供介面給到各流量入口方去選擇。
目前業務推廣過程中,主要遇到的入口方大致有以下幾種:
入口流量攜帶染色標相對邏輯比較簡單,這裡就不做詳細技術介紹,只做使用層面介紹
至此整個業務改造基本完成,從染色流量如何構造、流量標如何透傳、染色節點如何識別以及識別後重點染色邏輯如何處理等一整套流程就清晰了。
3.業務應用效果
3.1 實施路徑
染色專案整個實施路徑包含幾個階段:
專案立項&中介軟體改造(4月-6月)
包含基架改造(統一框架、閘道器、註冊中心、配置中心、超時中心、DMQ等)&客戶端改造&釋出平臺改造等等,以及改造完成後基礎鏈路驗證
線上灰度&全鏈路服務適配(7月~8月)
7月初:5個交易&中介軟體相關服務升級相關jar包帶上線進行驗證,保證不會對染色改造不會對生產有影響。
8月份:開始推進全域應用進行染色相關jar包升級
獨立專案使用(9月)
9月底之前,已經有若干獨立專案應用染色環境測試驗證完成
業務迭代使用(10月~11月)
10月份開始嘗試推進全業務進行染色環境試用排錯
試用結束,逐步推進迭代使用染色環境
3.2 業務使用效果
獨立專案:目前全域的獨立專案已全量切換至染色環境測試。
版本迭代:就最新的版本迭代使用結果來看,全域95%以上的需求都可以使用染色環境測試。
剩餘5%的需求場景主要是涉及以下兩個方面:
- 資料隔離:目前已有方案在支援,會涉及少量需求支撐。
- 前端染色:目前染色環境主要解決了後端染色的需求,部分場景需求依賴前端染色(多前端支援),方案也基本落地,會配合後端染色一起應用。
4.總結
染色環境現階段解決了測試環境衝突和測試環境穩定性的問題,並且相較之前多套獨立環境的方案,在成本上也有比較大的節省。後續得物也會嘗試用染色的能力解決生產灰度釋出問題,相信也會有不錯的效果。
*文/大地
關注得物技術,每週一三五晚18:30更新技術乾貨
要是覺得文章對你有幫助的話,歡迎評論轉發點贊~