得物染色環(huán)境落地實(shí)踐
1、背景
測(cè)試環(huán)境治理一直是各大公司非常重要的一個(gè)課題,測(cè)試環(huán)境穩(wěn)定性很大程度影響迭代開(kāi)發(fā)&測(cè)試效率。
綜合來(lái)看,測(cè)試環(huán)境不穩(wěn)定的原因主要有以下幾點(diǎn):
測(cè)試環(huán)境的變更非終態(tài)變更,經(jīng)常會(huì)有代碼發(fā)布/配置發(fā)布導(dǎo)致服務(wù)無(wú)法啟動(dòng)或者鏈路有問(wèn)題的情況。
變更頻繁,開(kāi)發(fā)需要聯(lián)調(diào)、測(cè)試需要迭代測(cè)試,代碼需要變更,配置也需要變更,權(quán)限控制就比較難做,增加了測(cè)試環(huán)境不穩(wěn)定性。
并行需求,同一時(shí)間單個(gè)應(yīng)用需要多個(gè)分支同時(shí)支持多個(gè)需求的測(cè)試,測(cè)試環(huán)境資源的搶占和沖突比較明顯。
得物測(cè)試環(huán)境穩(wěn)定性治理也經(jīng)歷了幾個(gè)階段:
- 2020~2021:多套物理環(huán)境隔離方案(基于ECS)
T0、T1、T2三套測(cè)試環(huán)境,每套環(huán)境物理隔離,無(wú)資源沖突和共享。
規(guī)劃T1用于迭代測(cè)試、T0用于集成回歸、T2用于獨(dú)立項(xiàng)目分配使用,但在實(shí)際使用過(guò)程中,業(yè)務(wù)測(cè)試并行太多,沖突比較明顯,環(huán)境就開(kāi)始亂用了,誰(shuí)有需求就隨便占用一套環(huán)境使用了。結(jié)果就是沒(méi)有一套穩(wěn)定的環(huán)境,測(cè)試有效性無(wú)法保障,并行項(xiàng)目環(huán)境沖突也無(wú)法解決。
- 2021~2022:MF全鏈路容器環(huán)境方案(基于容器)
隨著業(yè)務(wù)增長(zhǎng),3套測(cè)試環(huán)境已明顯不能滿足業(yè)務(wù)需求,因此去年得物基于容器快速搭建了10套MF環(huán)境用于支撐獨(dú)立項(xiàng)目的測(cè)試。
MF環(huán)境基于T0搭建,DB和T0共享,其他所有資源均獨(dú)立,目的是做到業(yè)務(wù)只需保障T0的穩(wěn)定性,所有MF環(huán)境可快速基于T0同步最新服務(wù)和最新配置,做到環(huán)境隨用隨取,解決并行項(xiàng)目環(huán)境沖突問(wèn)題。
實(shí)際實(shí)施過(guò)程中,項(xiàng)目環(huán)境沖突的問(wèn)題解決了,但是MF環(huán)境的穩(wěn)定性問(wèn)題依舊比較嚴(yán)重,維護(hù)成本巨大,主要原因集中在:
T0環(huán)境穩(wěn)定性,并非所有域都在T0集成回歸,導(dǎo)致T0穩(wěn)定性無(wú)法保障
MF同步了T0之后會(huì)因?yàn)楦鞣N各樣的原因需要二次調(diào)試驗(yàn)收(新增服務(wù)丟失、配置不全/錯(cuò)亂等)
MF環(huán)境使用過(guò)程中,基礎(chǔ)服務(wù)(sso、網(wǎng)關(guān)、中間件)等相關(guān)變更無(wú)法及時(shí)更新到MF環(huán)境,影響業(yè)務(wù)測(cè)試
因此在2022年下半年,開(kāi)始嘗試用染色環(huán)境解決環(huán)境穩(wěn)定性問(wèn)題。
- 2022年:染色環(huán)境方案(基于流量隔離)
染色環(huán)境是基于流量隔離的方案,通過(guò)流量標(biāo)透?jìng)鞯姆绞?,把基?zhǔn)環(huán)境流量和染色環(huán)境流量隔離開(kāi),實(shí)現(xiàn)多環(huán)境的方案,支持并行測(cè)試互不影響。
相較于MF環(huán)境而言,不需要維護(hù)多套全鏈路環(huán)境,維護(hù)成本降低了。所有變更的服務(wù)都在染色環(huán)境部署的話,基準(zhǔn)環(huán)境穩(wěn)定性就會(huì)提升,相當(dāng)于所有環(huán)境的穩(wěn)定性都提升了。
下面主要介紹得物染色環(huán)境是如何做的
2、染色環(huán)境方案
2.1 基本思路
如下圖所示,最初的設(shè)想是:
- 服務(wù)可以按照流量標(biāo)把流量路由到相應(yīng)染色服務(wù)上
- 如果染色標(biāo)對(duì)應(yīng)染色環(huán)境沒(méi)有此服務(wù),則流量會(huì)走到基準(zhǔn)環(huán)境
- 如果染色環(huán)境服務(wù)添加了,沒(méi)有部署,或者部署了服務(wù)進(jìn)程掛了,則流量會(huì)報(bào)錯(cuò)而并非走到基準(zhǔn)環(huán)境(避免一些服務(wù)異常問(wèn)題沒(méi)有暴露)
- DB、MQ、Redis等中間件期望用同一套,避免浪費(fèi)
基于此設(shè)想,需要從哪些地方入手去改造以支持染色環(huán)境呢?可以從設(shè)想拆解去解決:
- 流量標(biāo)如何透?jìng)鳎?/li>
- 流量路由如何路由到染色節(jié)點(diǎn)?
rpc接口如何路由到染色節(jié)點(diǎn)?
MQ消息如何讓染色環(huán)境consumer消費(fèi)?
- 解決完流量標(biāo)透?jìng)鲉?wèn)題,以及染色路由問(wèn)題后,需要考慮流量發(fā)起方如何把染色標(biāo)帶上?
2.2 實(shí)現(xiàn)方案
以下方案只做流量隔離,DB數(shù)據(jù)層不做隔離
流量標(biāo)如何透?jìng)鳎?/strong>
首先流量標(biāo)在流量入口層會(huì)放到http header里面的x-infr-flowtype字段:
從流量到網(wǎng)關(guān)后,服務(wù)鏈路上面流量標(biāo)往下透?jìng)鞯姆绞绞峭ㄟ^(guò)OpenTracing規(guī)范中的baggage能力,從header里面獲取染色標(biāo),并塞到trace里面向下透?jìng)鳌?/p>
這樣整個(gè)鏈路里面就都能拿到染色標(biāo)了
流量路由如何路由到染色節(jié)點(diǎn)?
這里分兩塊考慮:
(1)rpc調(diào)用,拿到染色標(biāo)之后,如何找到染色節(jié)點(diǎn)?這里要解決的是怎么識(shí)別染色節(jié)點(diǎn)
(2)MQ消息,producer如何發(fā)送帶染色標(biāo)的消息,consumer如何處理帶染色標(biāo)的消息
- 服務(wù)注冊(cè)--識(shí)別染色節(jié)點(diǎn)
首先染色環(huán)境創(chuàng)建的時(shí)候,會(huì)定義好染色標(biāo):
在此染色環(huán)境添加服務(wù)部署的時(shí)候,默認(rèn)會(huì)把染色標(biāo)注入到環(huán)境變量COLORING_ENV容器發(fā)布配置頁(yè)面會(huì)自動(dòng)增加COLORING_ENV變量
至此,服務(wù)啟動(dòng)時(shí)已可以讀到COLORING_ENV環(huán)境標(biāo)變量了,下一步就看注冊(cè)中心怎么去區(qū)分染色節(jié)點(diǎn)了.
首先服務(wù)在添加到染色環(huán)境的時(shí)候,服務(wù)會(huì)在注冊(cè)中心染色場(chǎng)增加一個(gè)節(jié)點(diǎn),標(biāo)明該服務(wù)在此染色環(huán)境是有服務(wù)節(jié)點(diǎn)存在的。
染色場(chǎng)主要解決的問(wèn)題是:如果染色節(jié)點(diǎn)掛了,染色環(huán)境流量應(yīng)該判斷該染色環(huán)境是否應(yīng)該有染色節(jié)點(diǎn),有的話就報(bào)錯(cuò),沒(méi)有的話才會(huì)走到基準(zhǔn)環(huán)境。避免測(cè)試問(wèn)題未暴露。
染色場(chǎng):CE_<ServiceName>
染色場(chǎng)服務(wù)節(jié)點(diǎn):<COLORING_ENV>:80
其次在服務(wù)注冊(cè)時(shí)候,服務(wù)節(jié)點(diǎn)信息和方法注冊(cè)會(huì)攜帶染色標(biāo)<coloring_env>:
至此,注冊(cè)中心就可以基于染色標(biāo)識(shí)別染色節(jié)點(diǎn),業(yè)務(wù)服務(wù)(基于fusion框架)可以根據(jù)Trace中的染色標(biāo)結(jié)合注冊(cè)中心染色節(jié)點(diǎn)做染色流量路由。
- MQ改造--識(shí)別和處理MQ消息
MQ主要解決的是,染色環(huán)境的消息生產(chǎn)者producer發(fā)送的消息,只被染色環(huán)境的消費(fèi)者消費(fèi),染色環(huán)境如果沒(méi)有消費(fèi)節(jié)點(diǎn),則由基準(zhǔn)環(huán)境消費(fèi)者消費(fèi)。
這里之前討論了兩種做法:
第一種是基于Topic隔離的方案,每套染色環(huán)境使用不同的topic進(jìn)行通信,這樣隔離性比較好,消息不容易串掉。
第二種是Topic不隔離,所有染色環(huán)境共用一個(gè)topic,生產(chǎn)者Producer在生產(chǎn)消息時(shí)候把染色標(biāo)帶上,consumer每套染色環(huán)境有一個(gè),consumer在做消費(fèi)時(shí)候會(huì)判斷消息里面的染色標(biāo)和本地染色標(biāo)是否一致,如果一致則消費(fèi),如果不一致則直接返回ACK不走具體消費(fèi)邏輯。
目前選擇的是第二種方案,下面基于第二種方案做詳細(xì)介紹:
基本流程
如圖所示:
ServiceB_Color1會(huì)自動(dòng)注冊(cè)GID_Color1_Topic消費(fèi)組,監(jiān)聽(tīng)Topic_A。Color2和Color3環(huán)境一樣。
帶Color1的消息由ServiceA_Color1生產(chǎn),ServiceB_Color1消費(fèi)。
帶Color2的消息由ServiceA_Color2生產(chǎn),ServiceB消費(fèi),因?yàn)镾erviceB在Color2染色環(huán)境沒(méi)有節(jié)點(diǎn)
帶Color3的消息由于染色環(huán)境Color3沒(méi)有ServiceA_Color3節(jié)點(diǎn),則帶Color3的流量會(huì)打到基準(zhǔn)環(huán)境ServiceA,此時(shí)ServiceA會(huì)生產(chǎn)帶Color3的消息,此消息由ServiceB_Color3消費(fèi)
配合業(yè)務(wù)說(shuō)明:
染色環(huán)境在啟動(dòng)時(shí)候,帶染色標(biāo)的GID會(huì)自動(dòng)創(chuàng)建,eg:原GID是GID_AAA,染色自動(dòng)創(chuàng)建的GID為GID_<coloring_env>_AAA
下面看消息的內(nèi)容和處理邏輯:
如上圖:染色消息屬性里面會(huì)增加DMQ_ENV_TAG字段,添加染色標(biāo),然后對(duì)應(yīng)染色環(huán)境訂閱組才會(huì)消費(fèi)。
看上面這張圖,會(huì)發(fā)現(xiàn)“貌似”所有染色環(huán)境都消費(fèi)了,其實(shí)是其他環(huán)境直接返回了ACK,未走具體的消費(fèi)邏輯,具體可以看日志。
代碼說(shuō)明:基于Message里面染色標(biāo)msgTag和本地服務(wù)染色標(biāo)envTag進(jìn)行判斷做消費(fèi)邏輯區(qū)分。
染色流量入口攜帶染色標(biāo)
解決完染色標(biāo)透?jìng)鳎约叭旧珮?biāo)邏輯處理后,剩下就是如何在流量發(fā)起方把染色標(biāo)給帶上了,其實(shí)就是把染色標(biāo)塞到header里面的x-infr-flowtype字段。
其中染色環(huán)境列表的獲取由發(fā)布平臺(tái)提供接口給到各流量入口方去選擇。
目前業(yè)務(wù)推廣過(guò)程中,主要遇到的入口方大致有以下幾種:
入口流量攜帶染色標(biāo)相對(duì)邏輯比較簡(jiǎn)單,這里就不做詳細(xì)技術(shù)介紹,只做使用層面介紹
流量入口方 | 染色標(biāo)傳遞 | 備注 |
App端 | 從發(fā)布平臺(tái)獲取染色標(biāo)列表,選擇染色環(huán)境后,所有請(qǐng)求在Header里面添加x-infr-flowtype字段向下透?jìng)魅旧珮?biāo) | |
Web端 | 點(diǎn)擊ENV彈窗選擇染色標(biāo) | 同上 |
飛書(shū)回調(diào) | 回調(diào)URL參數(shù)增加x-infr-flowtype=<染色標(biāo)>字段 | |
Job場(chǎng)景 | 目前是半自動(dòng)方案: 染色環(huán)境&基準(zhǔn)環(huán)境注冊(cè)到同一個(gè)Job 默認(rèn)job會(huì)隨機(jī)選一個(gè)節(jié)點(diǎn)執(zhí)行 如果需要指定到染色節(jié)點(diǎn)執(zhí)行,用戶可手動(dòng)在job編輯界面添加染色標(biāo) | 目前不考慮數(shù)據(jù)隔離場(chǎng)景 |
Canal訂閱 | 目前是半自動(dòng)方案: 染色節(jié)點(diǎn)和基準(zhǔn)節(jié)點(diǎn)Consumer訂閱同一個(gè)topic 默認(rèn)MQ消息不會(huì)帶染色標(biāo),則只會(huì)有基準(zhǔn)環(huán)境消費(fèi) 如果需要指定染色環(huán)境消費(fèi),用戶可以手動(dòng)在job編輯界面添加染色標(biāo) | 目前不考慮數(shù)據(jù)隔離場(chǎng)景 |
至此整個(gè)業(yè)務(wù)改造基本完成,從染色流量如何構(gòu)造、流量標(biāo)如何透?jìng)鳌⑷旧?jié)點(diǎn)如何識(shí)別以及識(shí)別后重點(diǎn)染色邏輯如何處理等一整套流程就清晰了。
3、業(yè)務(wù)應(yīng)用效果
3.1 實(shí)施路徑
染色項(xiàng)目整個(gè)實(shí)施路徑包含幾個(gè)階段:
- 項(xiàng)目立項(xiàng)&中間件改造(4月-6月)
包含基架改造(統(tǒng)一框架、網(wǎng)關(guān)、注冊(cè)中心、配置中心、超時(shí)中心、DMQ等)&客戶端改造&發(fā)布平臺(tái)改造等等,以及改造完成后基礎(chǔ)鏈路驗(yàn)證
- 線上灰度&全鏈路服務(wù)適配(7月~8月)
7月初:5個(gè)交易&中間件相關(guān)服務(wù)升級(jí)相關(guān)jar包帶上線進(jìn)行驗(yàn)證,保證不會(huì)對(duì)染色改造不會(huì)對(duì)生產(chǎn)有影響。
8月份:開(kāi)始推進(jìn)全域應(yīng)用進(jìn)行染色相關(guān)jar包升級(jí)
- 獨(dú)立項(xiàng)目使用(9月)
9月底之前,已經(jīng)有若干獨(dú)立項(xiàng)目應(yīng)用染色環(huán)境測(cè)試驗(yàn)證完成
- 業(yè)務(wù)迭代使用(10月~11月)
10月份開(kāi)始嘗試推進(jìn)全業(yè)務(wù)進(jìn)行染色環(huán)境試用排錯(cuò)
試用結(jié)束,逐步推進(jìn)迭代使用染色環(huán)境
3.2 業(yè)務(wù)使用效果
獨(dú)立項(xiàng)目:目前全域的獨(dú)立項(xiàng)目已全量切換至染色環(huán)境測(cè)試。
版本迭代:就最新的版本迭代使用結(jié)果來(lái)看,全域95%以上的需求都可以使用染色環(huán)境測(cè)試。
剩余5%的需求場(chǎng)景主要是涉及以下兩個(gè)方面:
數(shù)據(jù)隔離:目前已有方案在支持,會(huì)涉及少量需求支撐。
前端染色:目前染色環(huán)境主要解決了后端染色的需求,部分場(chǎng)景需求依賴前端染色(多前端支持),方案也基本落地,會(huì)配合后端染色一起應(yīng)用。
4、總結(jié)
染色環(huán)境現(xiàn)階段解決了測(cè)試環(huán)境沖突和測(cè)試環(huán)境穩(wěn)定性的問(wèn)題,并且相較之前多套獨(dú)立環(huán)境的方案,在成本上也有比較大的節(jié)省。后續(xù)得物也會(huì)嘗試用染色的能力解決生產(chǎn)灰度發(fā)布問(wèn)題,相信也會(huì)有不錯(cuò)的效果。