自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

攜程代碼分析平臺,快速實現(xiàn)精準(zhǔn)測試與應(yīng)用瘦身

開發(fā) 后端
本文主要基于后端Java應(yīng)用介紹如何實現(xiàn)代碼分析平臺化,并借助平臺工具實現(xiàn)精準(zhǔn)測試和應(yīng)用瘦身。

作者簡介

Kevin,攜程后端開發(fā)專家,追求通過深入業(yè)務(wù)來簡化系統(tǒng),對底層算法、數(shù)據(jù)分析有濃厚興趣。

一、引言

1.1 背景

微服務(wù)架構(gòu)下,產(chǎn)研分工精細(xì),需求迭代頻繁,隨著需求的不斷迭代,應(yīng)用數(shù)、代碼量及測試用例越積越多;需求迭代(尤其是有新人加入)的過程中,產(chǎn)品經(jīng)理需要通過開發(fā)了解現(xiàn)狀和歷史邏輯,開發(fā)人員翻閱歷史代碼花費的時間和精力越來越大,測試人員上線前需要回歸的用例也越來越多,嚴(yán)重影響了需求迭代的效率。

1.2 現(xiàn)狀分析

目前攜程旅游BG的后端開發(fā)人均應(yīng)用數(shù)超過4個,人均維護(hù)的代碼行近20萬行;每月平均需求迭代的發(fā)布超過2千次,其中核心應(yīng)用數(shù)占比及其發(fā)布次數(shù)占比都超過8成。

為了提高需求迭代的效率,旅游技術(shù)團(tuán)隊設(shè)計開發(fā)代碼分析平臺,對應(yīng)用的現(xiàn)狀(主要是源代碼和測試用例)進(jìn)行綜合分析發(fā)現(xiàn):生產(chǎn)應(yīng)用中高達(dá)三分之一的代碼屬于dead代碼(沒有被引用,也沒有任何生產(chǎn)流量),嚴(yán)重影響開發(fā)效率;日常迭代中68%的自動化回歸用例與當(dāng)前迭代無關(guān),但是為了保障上線質(zhì)量,測試人員需要對每條失敗用例進(jìn)行分析排查,不僅影響當(dāng)前的交付進(jìn)度,而且隨著需求的快速迭代,自動化測試的可持續(xù)性堪憂。

二、代碼分析規(guī)劃

本文主要基于后端Java應(yīng)用介紹如何實現(xiàn)代碼分析平臺化,并借助平臺工具實現(xiàn)精準(zhǔn)測試和應(yīng)用瘦身。平臺可以幫助開發(fā)人員識別無效代碼,在短時間內(nèi)以最小的風(fēng)險完成應(yīng)用瘦身,極大的提高研發(fā)的效率;同時通過平臺的用例知識庫進(jìn)行精準(zhǔn)測試,在需求迭代過程中只執(zhí)行本次改動相關(guān)的用例,極大的提高自動化回歸的效率和可持續(xù)性。如下圖:

圖片

圖1 代碼分析與精準(zhǔn)測試、應(yīng)用瘦身

2.1 分析應(yīng)用現(xiàn)狀

通過對應(yīng)用系統(tǒng)綜合分析,形成知識庫。分析的對象包括源代碼(不含第三方引用)、對外提供的服務(wù)(包括api、任務(wù)以及消息)、自動化用例、日常迭代變更以及方法維度的生產(chǎn)流量等。知識庫包含應(yīng)用基本信息、統(tǒng)計信息(例如代碼規(guī)模、方法規(guī)模、用例規(guī)模)、方法鏈路信息、用例鏈路等。

2.2 工具化及流程閉環(huán)

利用分析得到的知識庫,針對特定場景進(jìn)行工具化和流程閉環(huán),輔助應(yīng)用治理。

例如精準(zhǔn)測試場景,平臺可以與發(fā)布流程結(jié)合起來,開發(fā)提測后自動識別變更內(nèi)容,并智能推薦自動化用例并執(zhí)行,將執(zhí)行結(jié)果實時同步給開發(fā)和測試人員,實現(xiàn)變更→發(fā)布→用例推薦、執(zhí)行、反饋→修復(fù)變更的閉環(huán)。

應(yīng)用瘦身場景,從開發(fā)角度來看,平臺需提供多視角的輔助分析工具,幫助開發(fā)人員確定方法/類是否可以安全的刪除;從管理角度來看,平臺需劃定應(yīng)用治理前的基線,并將無效代碼比例作為應(yīng)用長期治理對象,從而實時評估下屬治理的進(jìn)度和效果,形成治理過程的閉環(huán)。

三、代碼分析原理

代碼分析的基本單元是方法,主體是應(yīng)用的整個生命周期,從應(yīng)用的代碼倉庫建立以及研發(fā)完成代碼開發(fā),到測試發(fā)布,再到生產(chǎn)運行,我們對不同階段方法的關(guān)聯(lián)信息進(jìn)行分析,最終得到一個完整的知識庫,分析流程及定義如下圖:

圖片圖2 代碼分析原理

3.1 靜態(tài)分析

通過源代碼解析工具解析出所有的方法聲明及調(diào)用關(guān)系。

針對Java語言常見的解析工具及原理如下:

圖片



推薦使用java-callgraph2,理由是java-callgraph2專注于類和方法之間調(diào)用關(guān)系的分析,解決了很多常見問題,例如thread、lambda、stream使用場景的調(diào)用關(guān)系缺失等,并且在git上開源,引入源碼可實現(xiàn)定制化。

3.2 半動態(tài)分析

通過字節(jié)碼增強(qiáng)技術(shù)(如下圖)和用例回放相結(jié)合,獲取用例執(zhí)行的方法鏈,再基于靜態(tài)分析進(jìn)行方法映射,達(dá)到半動態(tài)的效果。半動態(tài)分析工具推薦使用攜程的開源平臺AREX。

圖片圖3 字節(jié)碼增強(qiáng)技術(shù)

3.3 動態(tài)分析

動態(tài)分析是一種代碼運行時的采集分析,主要方式是收集生產(chǎn)環(huán)境方法的執(zhí)行次數(shù),以確認(rèn)方法是否有效。目前主要有兩種做法,一種是通過打樁的方式,類似于半動態(tài)分析。該方式雖然能夠獲取準(zhǔn)確完整的運行時信息,但考慮到存在代碼入侵并且可能對生產(chǎn)服務(wù)器性能產(chǎn)生影響,不建議采用這種方法。

另一種方法是利用Java虛擬機(jī)(JVM)的方法計數(shù)器,我們知道JVM采用的是JIT(Just-In-Time)編譯機(jī)制,方法執(zhí)行過程如下圖:

圖片圖4 JVM-JIT方法編譯執(zhí)行流程

這種方式對代碼無入侵,缺點是訪問JVM方法計數(shù)器需要attach虛擬機(jī)進(jìn)程導(dǎo)致STW(Stop The World),并且方法計數(shù)并不代表真正流量,只能反映方法有沒有被執(zhí)行以及執(zhí)行的頻度(幸運的是這對我們的場景已經(jīng)足夠了)。

綜合考慮,推薦使用第二種方式,另外為了最大程度的降低采集流量期間STW對業(yè)務(wù)的影響,需要選取最適合采集的實例并提前停止對外服務(wù)(集群部署可以通過實例拉出實現(xiàn))。

四、代碼分析平臺化

確定了代碼分析平臺化的目標(biāo),并闡述了代碼分析的基本原理,接下來我們重點剖析平臺化的三個關(guān)鍵步驟。

4.1 步驟一:建立知識庫

建立知識庫是代碼分析平臺化的基礎(chǔ),知識庫可以將需求迭代的流程串連起來,并為后續(xù)分析數(shù)據(jù)(用例、流量等)的落地提供載體。

4.1.1 獲取應(yīng)用入口

應(yīng)用入口指的是應(yīng)用對外提供的服務(wù),通常包括對外提供的api、應(yīng)用定時調(diào)度job、消息(例如qmq)的消費者;應(yīng)用入口一般都是通過注解標(biāo)記并自動注冊上線,原理如圖所示,運行時主動向注冊中心注冊實例和服務(wù),被動接受調(diào)度和請求。

圖片

圖5 微服務(wù)注冊發(fā)現(xiàn)流程

獲取應(yīng)用入口的最簡單方式是通過代碼分析根據(jù)注解識別。另外,多團(tuán)隊協(xié)作場景的api契約往往采用集中管理模式,應(yīng)用通過第三方包引入api契約定義,為了避免大量的第三方引用解析,建議通過注冊中心獲取應(yīng)用入口。

4.1.2 獲取源代碼

鏡像指的是源代碼經(jīng)過編譯、打包、檢測驗證后得到的容器加載對象,鏡像是靜態(tài)分析的主要輸入。獲取源代碼則是為了得到準(zhǔn)確的源碼統(tǒng)計信息及變更信息。

考慮到開發(fā)人員在特定需求迭代過程中會多人協(xié)作、多次提交代碼,因此獲取源代碼及鏡像的時機(jī)建議在集群部署完成后、對外提供服務(wù)前,這樣可以減少不必要分析、節(jié)約資源、簡化分析流程以及減少對開發(fā)和測試的干擾。

4.1.3 靜態(tài)分析及存儲

通過靜態(tài)分析可以得到方法間的調(diào)用關(guān)系,以及對方法進(jìn)行標(biāo)記(api、job、consumer、屬性等)和染色(重寫、繼承、引用、可達(dá)等)。靜態(tài)分析流程如下圖所示:

圖片圖6 靜態(tài)分析流程

實體數(shù)據(jù)建議使用關(guān)系數(shù)據(jù)庫存儲,考慮到方法間的調(diào)用關(guān)系復(fù)雜多變且層級深,推薦使用圖數(shù)據(jù)庫存儲方法調(diào)用關(guān)系,不僅檢索的復(fù)雜度更低、性能更好,而且能夠比較直觀的反映系統(tǒng)現(xiàn)狀(通過Nebula-Graph存儲并檢索舉例如下圖)。

圖片圖7 方法調(diào)用鏈路圖展示

4.2 步驟二:完善知識庫用例信息

在建立知識庫的基礎(chǔ)上,測試作為需求上線前的必備步驟,對測試用例的分析并融入知識庫至關(guān)重要。這個步驟我們主要通過用例回放收集用例經(jīng)過的內(nèi)部方法和對外api,結(jié)合源碼對比得到的變更方法分析出需求改動直接、間接影響的入口和用例。

4.2.1 用例回放

用例回放指的是在用例執(zhí)行的同時收集代碼執(zhí)行信息。執(zhí)行用例回放需要滿足兩個前提條件,一是需要有一套自動化用例測試平臺,能夠維護(hù)并調(diào)度執(zhí)行自動化用例;二是需要在系統(tǒng)運行時進(jìn)行打樁,能夠在用例執(zhí)行的過程中識別用例和方法調(diào)用信息,并對外輸出。

大多數(shù)互聯(lián)網(wǎng)企業(yè)都有自建的自動化測試平臺,這里不做展開;系統(tǒng)運行時打樁的實現(xiàn)推薦使用開源AREX,不需要修改業(yè)務(wù)代碼,僅需系統(tǒng)鏡像打包時加載代理服務(wù),對系統(tǒng)運行時的影響安全可控。

4.2.2 分析流程

通過半動態(tài)分析(流程如下圖),獲取用例執(zhí)行過程中途經(jīng)的方法鏈路,補(bǔ)充知識庫中通過用例建立起來的方法關(guān)聯(lián)關(guān)系。

圖片圖8 半動態(tài)分析流程

基于方法調(diào)用關(guān)系在圖中的存儲,用例和方法的關(guān)系也采用圖數(shù)據(jù)庫的存儲,只需要再補(bǔ)充新類型的點(用例)和邊(用例調(diào)用方法)即可,其表現(xiàn)方式更為直觀(如下圖)。

圖片圖9 用例方法調(diào)用鏈圖展示

4.3 步驟三:完善知識庫流量信息

對源代碼、用例的分析是建立在冷數(shù)據(jù)加載的基礎(chǔ)上,應(yīng)用代碼的質(zhì)量、測試的有效性最終體現(xiàn)在應(yīng)用對外提供服務(wù)的過程中,運行時的數(shù)據(jù)不可或缺。這個環(huán)節(jié)我們主要介紹基于動態(tài)分析的原理,如何進(jìn)行生產(chǎn)流量采集,如何將采集數(shù)據(jù)跟知識庫結(jié)合起來,為后續(xù)的工具化和流程閉環(huán)提供數(shù)據(jù)支撐。

4.3.1 生產(chǎn)流量采集

生產(chǎn)流量采集主要包含兩部分內(nèi)容,入口流量采集和應(yīng)用內(nèi)部方法流量采集。

入口流量主要指api(job任務(wù)/消息處理)被外部調(diào)度的情況。作為日常排查問題和監(jiān)控的重點,這部分?jǐn)?shù)據(jù)通常作為微服務(wù)架構(gòu)的基礎(chǔ)能力,可以直接通過公共基礎(chǔ)服務(wù)獲取,這里不做展開。

應(yīng)用內(nèi)部方法流量采集的原理(動態(tài)分析)前面已經(jīng)介紹過,這里重點介紹集群部署的場景下,采集實例選取的三個基本原則。

首先是保障采集對生產(chǎn)影響最小。主要基于采集需要暫停實例服務(wù)的考量,實例拉出前要做集群服務(wù)能力評估,確保服務(wù)能力不能下降過多(例如集群實例數(shù)少于3個的情況下不建議自動拉出),拉出后要給未完成的業(yè)務(wù)線程保留一定的處理時間,采集異?;蛘邥r間超過一定時長能夠及時中斷恢復(fù)拉入。另外針對job類應(yīng)用建議owner選擇合適時機(jī)手工采集。

其次是確保采集內(nèi)容有效。方法流量采集本質(zhì)上是JVM底層方法計數(shù)信息,因此如果實例創(chuàng)建時間過短(例如自動擴(kuò)容)或者集群本身只針對特定場景服務(wù)(例如操作路由),很多場景都沒有被執(zhí)行到,采集的意義就不大。

最后是保障采集過程可持續(xù)。隨著業(yè)務(wù)快速迭代,生產(chǎn)流量是不斷變化的,因此流量采集需要周期性的持續(xù)進(jìn)行。

4.3.2 分析流程

通過動態(tài)分析(流程如下圖),將方法的流量信息補(bǔ)充到圖數(shù)據(jù)庫的點(方法)上,可以動態(tài)的反映方法被執(zhí)行情況,間接的反映方法及自動化用例的有效性。

圖片 圖10 動態(tài)分析流程

五、應(yīng)用場景 

在知識庫的基礎(chǔ)上,結(jié)合精準(zhǔn)測試和應(yīng)用瘦身兩個具體的應(yīng)用場景,實現(xiàn)工具化和流程閉環(huán),最終完成代碼分析平臺化建設(shè)。

5.1 精準(zhǔn)測試

5.1.1 用例執(zhí)行現(xiàn)狀

自動化用例回歸作為應(yīng)用發(fā)布生產(chǎn)前的必經(jīng)環(huán)節(jié),有兩項重要的評估標(biāo)準(zhǔn):用例執(zhí)行成功率和新增代碼行的覆蓋率。在沒有用例推薦之前,一般采用人工選取執(zhí)行和全量執(zhí)行兩種方式。

人工選取的優(yōu)點是用例有針對性,缺點是不僅效率低而且容易漏選;全量執(zhí)行雖然可以避免用例選取缺漏,同時可以提高增量代碼行的覆蓋率,但是用例執(zhí)行成功率無法保障,往往需要對執(zhí)行失敗的任務(wù)一一排查,花費大量的時間和精力,大多數(shù)情況下失敗的用例與迭代的需求并不相關(guān),更令測試同學(xué)頭疼的是隨著需求迭代自動化用例在不斷增加,費力度逐漸升高。

5.1.2 用例推薦

基于代碼分析平臺,應(yīng)用生產(chǎn)發(fā)布前,可以通過對源代碼進(jìn)行對比分析獲取變更的具體方法,獲取變更通常需要代碼版本管理工具和對比組件,目前互聯(lián)網(wǎng)企業(yè)應(yīng)用比較廣泛的代碼倉庫管理工具是git,對比組件推薦使用code diff。

方法聲明不變的變更(例如修改、刪除),知識庫中已經(jīng)收集了方法調(diào)用鏈、用例方法鏈,并且對方法進(jìn)行了入口標(biāo)記和染色,我們可以準(zhǔn)確的識別其關(guān)聯(lián)的入口及用例;方法聲明變化的變更(例如新增、增加入?yún)ⅲ?,我們利用實時靜態(tài)分析可以通過調(diào)用鏈追溯到影響的入口,通過入口找到關(guān)聯(lián)的用例。用例推薦功能如下圖,每次只執(zhí)行代碼變更相關(guān)的用例。

圖片

圖11 用例推薦流程

5.1.3 流程閉環(huán)

解決了如何準(zhǔn)確的推薦用例,接下里需要結(jié)合需求迭代的基本流程和應(yīng)用發(fā)布流程將代碼變更、用例推薦、用例執(zhí)行以及結(jié)果反饋串連起來(如下圖),實現(xiàn)流程的閉環(huán),才能更好的發(fā)揮代碼分析平臺的作用,最終提高需求迭代效率和質(zhì)量。

圖片圖12 精準(zhǔn)測試流程閉環(huán)

5.1.4 度量方法及效果

前面提到自動化用例執(zhí)行效果的評估標(biāo)準(zhǔn)主要是用例執(zhí)行成功率和增量行覆蓋率,成功率主要靠用例本身的質(zhì)量來保障,增量行覆蓋率可以作為衡量精準(zhǔn)測試準(zhǔn)確性的度量方法之一。理論上精準(zhǔn)測試的增量行覆蓋率只要不能接近全量執(zhí)行的增量行覆蓋率,就說明推薦用例存在缺失。

經(jīng)過驗證,目前我們精準(zhǔn)測試的增量行覆蓋率可以達(dá)到全量執(zhí)行的99.2%(偏差主要來自于環(huán)境依賴),全面推廣后平均減少了68%與當(dāng)次需求迭代無關(guān)的用例回歸。隨著自動化用例的不斷增加,精準(zhǔn)推薦已經(jīng)成為自動化回歸不可或缺的一環(huán)。

5.2 應(yīng)用瘦身

5.2.1 應(yīng)用代碼現(xiàn)狀

應(yīng)用經(jīng)歷一段時間的需求迭代之后無效代碼就會開始累積,究其原因主要有三個方面,一是需求變更后部分分支不會再被執(zhí)行到,由于種種原因沒有來得及重構(gòu);二是項目上線初期的臨時檢測對比的分支,項目上線后沒有及時清除;三是上游場景變化導(dǎo)致下游部分場景不再被執(zhí)行,但下游自身又無法識別。

過高比例的無效代碼不僅影響系統(tǒng)的編譯速度,而且嚴(yán)重影響開發(fā)的效率,尤其是對于新接手的同學(xué),需要了解大量的代碼歷史背景才能熟悉系統(tǒng)現(xiàn)有的邏輯,而且代碼量越大邏輯越復(fù)雜,修改的風(fēng)險也就越高,即使經(jīng)驗豐富的工程師也不敢輕言重構(gòu)。

5.2.2 工具化

基于代碼分析的知識庫信息,以方法為基本單位進(jìn)行引用、入口以及生產(chǎn)流量的多維度分析(如下圖),并提供應(yīng)用分析工具,輔助開發(fā)人員快速的識別無效代碼,實現(xiàn)應(yīng)用瘦身。

圖片圖13 方法可達(dá)分析

5.2.3 流程閉環(huán)

從研發(fā)的角度看,刪除代碼存在一定的風(fēng)險,如果能夠便捷的通過工具獲取代碼的生產(chǎn)流量情況以及外部依賴情況,將極大的降低這種風(fēng)險,增強(qiáng)其應(yīng)用瘦身(包括代碼重構(gòu)和刪除)的信心;從團(tuán)隊管理的角度來看,如何衡量治理的效果、把控治理過程的風(fēng)險以及長遠(yuǎn)地評估無效代碼的合理范圍也同樣重要,因此平臺從研發(fā)和管理兩個角度實現(xiàn)了閉環(huán)(如下圖)。

圖片

圖14 應(yīng)用瘦身流程閉環(huán)

5.2.4 試點效果及經(jīng)驗

完成工具化和流程閉環(huán),我們拿團(tuán)隊內(nèi)部10%的應(yīng)用(100+)經(jīng)過1個月的試點,輕松實現(xiàn)了零故障刪除百萬級代碼行的目標(biāo)。其中15%的大規(guī)模應(yīng)用(代碼行大于20萬行)經(jīng)過瘦身后系統(tǒng)鏡像的生成時長從幾十分鐘級降至到幾分鐘(耗時包括編譯、UT執(zhí)行、合規(guī)掃描等)。代碼鏈路復(fù)雜度也明顯降低,如下圖所示。

圖片圖15 應(yīng)用瘦身前后方法鏈對比

經(jīng)過試點,我們總結(jié)了應(yīng)用瘦身需要嚴(yán)格遵守的三個原則,一是瘦身工具只是輔助,代碼刪除一定要由對應(yīng)用背景有一定了解的同學(xué)進(jìn)行;二是刪除代碼一定要經(jīng)過合作伙伴或leader的review;三是應(yīng)用瘦身是一個長期治理的過程,不能急于一時或一次了事。

六、總結(jié)

本文主要基于微服務(wù)架構(gòu)下為了提高需求迭代效率,通過代碼分析形成知識庫,針對精準(zhǔn)推薦和應(yīng)用瘦身兩個場景進(jìn)行工具化和流程閉環(huán),初步完成代碼分析平臺化建設(shè)。

目前已支持的場景還需要進(jìn)一步細(xì)化(例如應(yīng)用瘦身可以支持本地開發(fā)工具的插件化),結(jié)合當(dāng)前的知識庫,后續(xù)還可以支持更多的場景(例如工程復(fù)雜度、用例質(zhì)量等等)。本文只是拋磚引玉,為應(yīng)用治理提供了一種全新的思路,代碼分析平臺化是一個長期持續(xù)的工程,需要走的路還很長。

參考文獻(xiàn)

  • java-callgraph2:
    https://github.com/Adrninistrator/java-callgraph2
  • arex-agent-java: 
    https://github.com/arextest/arex-agent-java 
  • OpenJDK: https://openjdk.org/groups/hotspot/docs/Serviceability.html
  • JavaParser: https://javaparser.org/
責(zé)任編輯:張燕妮 來源: 攜程技術(shù)
相關(guān)推薦

2023-11-06 09:56:10

研究代碼

2024-11-12 14:19:53

2014-12-25 17:51:07

2022-07-15 12:58:02

鴻蒙攜程華為

2022-12-14 09:58:27

代碼平臺

2024-04-18 09:41:53

2024-03-22 15:09:32

2017-02-09 11:05:11

大數(shù)據(jù)用戶畫像技術(shù)

2021-10-08 16:25:33

數(shù)字化

2023-07-07 14:12:52

攜程開發(fā)

2014-04-16 13:55:20

2024-08-08 16:17:29

2025-03-18 12:23:25

2023-08-18 10:49:14

開發(fā)攜程

2022-03-30 18:39:51

TiDBHTAPCDP

2016-09-04 15:14:09

攜程實時數(shù)據(jù)數(shù)據(jù)平臺

2020-12-04 14:32:33

AndroidJetpackKotlin

2024-07-05 15:05:00

2023-08-04 09:46:36

開源技術(shù)

2017-07-06 19:57:11

AndroidMVP攜程酒店
點贊
收藏

51CTO技術(shù)棧公眾號