WOT徐冬晨:JVM—Sandbox 基於JVM的非侵入式運行期AOP解決方案

2020-12-20 51CTO

【51CTO.com原創稿件】2018年5月18-19日,由51CTO主辦的全球軟體與運維技術峰會在北京召開。來自全球企業的技術精英匯聚北京,暢談軟體技術前沿,共同探索運維技術的新邊界。而在本次大會上,除了眾星雲集的主論壇環節,12場分論壇更是各具特色,在19日下午的「微服務架構設計」分論壇上,來自阿里巴巴淘寶技術質量部測試研發工程師徐冬晨發表了精彩演講。身兼主持人和演講人雙重職責的徐冬晨輕鬆有活力的開場,為我們講述了JVM—Sandbox的產生背景以及它的優勢所在,包括應用場景、核心技術、開源幾個方面的內容。

JVM—Sandbox的產生背景

隨著軟體規模的擴大,系統功能的細分,要保證阿里巴巴整個系統穩定性,要做許多工具平臺和監控體系,辛勤的開發測試人員都需要做哪些工作呢?徐冬晨舉例說明,例如我們要做系統限流、流控、故障模擬、信息監控、鏈路跟蹤、問題定位等等,最應該關心的是,系統架構升級之後,對基礎業務有沒有影響,測試者要尋求自動化測試的方法,實現自動化的業務回歸。

對於寫接口測試的測試工程師來說,他們更想完成的一種方式是線上錄製、線下回放的方式進行業務回歸,這樣可以大大節省成本。如果要做這樣的一個回歸,其方法也是對方法的入參和返回值進行監控,或者是監控它整條鏈路上面會不會出問題。下面就是監控以及鏈路跟蹤,以及精準回歸。

徐冬晨列出了四個比較具體的場景,要保證它的穩定性的確需要做很多事情。當我們把這些東西做一個簡單的抽象之後,上面的這些工具平臺就做兩件事情:

***是方法的監聽與環繞管控,第二是行鏈路信息的獲取與統計。以方法的監聽與環繞管控為例,這就是用java,用大家最熟悉的NOP。但是使用NOP也是有些問題的,如果我們要有一個統一的監控平臺,監控系統代碼與代碼的比例也很重要。她看到過最誇張的一個系統,監控代碼和業務代碼的比例是1:2,就是1/3的代碼都是監控代碼,而且這種監控代碼是比較笨重的,是因為要發散,才能夠把它發上去,這就是問題的所在。

行鏈路方面,為了計算覆蓋率,如果我們要維持系統的靈活度,就不能因為要做一個問題定位,要加一行日誌,就重新做系統,我們在做穩定性平臺配套工具的時候,需要具備三個特點:

***:對於開發代碼是無侵入的。

    第二:要實時生效,因為問題解決的時候,要保留現場,所以要實時生效。

    第三:動態可插拔。

要做成這樣子,就需要一個動態字節碼增強解決方案。如上面所說,無論故障演練、強弱依賴檢測、流量錄製回訪、問題定位還是監控體系,如果我們每做這麼一個工具平臺,底層全部去實現一個動態字節碼增強的話,投入的成本是很高的,是有學習門檻的。上面衍生出來的這個平臺,***都會作用到一個系統裡面去,其實他們底層字節碼增強,這段代碼會不會相互幹擾,都是問題。為了解決這些問題,為了屏蔽字節碼增強的技術高門檻,為了降低研發和運營的成本,為了上層多個模塊可以動態管理。我們就開發出JVM--Sandbox。

JVM—Sandbox的優勢

JVM—Sandbox既有AOP通用API的便利,又有埋點的靈活,實時非侵入的AOP容器。它的功能方面,首先JVM—Sandbox是基於JVMTI技術規範,為觀察和改變代碼運行結果提供了即插即用模塊接口的容器。JVM-Sandbox為AOP提供了一個新的實現方案——以插樁代替代理。

使用人群:使用字節碼增強技術,進行工具開發、實現業務功能的開發、測試同學。

核心功能:首先它提供了一個字節碼增強統一API。其次它提供了無切入的容器,它跟你的目標機器之間其實是隔離的。第三就是我們的容器管理。你可以在JVM—Sandbox基礎上可以掛載多個模塊,每個模塊完成它自己的鏈路跟蹤、問題定位這些功能是可以同時掛載的。

利用Sandbox可以實現哪些功能呢?抽象出來是入參的感知與改變。返回值的感知與改變以及拋異常。流程的控制,執行之前返回,執行之前重新構造新的一個結果對象進行返回,異常之後重新拋出異常或者直接返回一個正常的結果,它可以幫你做這些事情。徐冬晨向大家做了一個簡單的介紹:

核心操作對象  

首先看核心操作對象,這是一個抽象的過程,我們已經在用的有一些開源的工具,包括定位工具、測試工具,我們抽象出來其實就是執行之前的觀察和異常觀察,還有執行之前的改變以及異常改變。其實這樣抽象完之後,我們的核心事件是三個,比如說我們transform事件,三個環節正常流轉和幹預流轉,以及行事件,行事件其實就是在每一個代碼行後面加一個插裝。

如何與目標進行隔離和通訊

那麼,如何保證Sandbox和目標機器之間是相互隔離的呢?做法非常簡單,用一句話概括的就是:破壞雙親委派機制和自定義ClassLoader完成類隔離。向Bootstrap ClassLoader注入一個Spy類來完成通訊。這個是最原始的雙親委派機制。

破壞雙親委派機制後,如果要加載一個類的時候,它會先去看當前的ClassLoader是否已經存在,如果沒有加載的話,它會委派它的父親,它的父ClassLoader去問,你是不是已經加載了,如果它也沒有加載的話,再向上詢問,一直詢問到 Boots trap ClassLoader。這個是原生的雙親委派機制。

破壞後的雙親委派機制變成了什麼?要掛載一個類,它會先看我當前的ClassLoader是不是加載了,如果沒加載,它會讓當前的ClassLoader嘗試著去加載,也就是它不再向它的父類去詢問,除非它無法加載的時候,它才會去問它的父ClassLoader說,你是不是已經加載了,如果父ClassLoader也沒有加載的話,它會讓父ClassLoader嘗試著去加載。這樣就完成了我的目標應用之間與Sandbox之間的隔離。

其實Sandbox在啟動的時候會做一些事件,它會為每一個Module,就是上層掛載的Module,以及Sandbox,每個Module都會去給它新建一個ClassLoader,Sandbox自己也會給它新建一個ClassLoader。這樣的話我們就完成了Sandbox與Module之間,以及Module與Module之間,以及他們與目標應用之間的隔離。

通訊其實就是我們在 Boots trap ClassLoader裡面會注入一個Spy類,這個Spy類負責目標應用與Sandbox之間的通訊,不是特別直觀。

如何做到動態插拔

談到如何去實現動態可插拔,徐冬晨用一句話概括:transform方法形變原生字節碼,事件監聽表管理模塊。為什麼要有這塊,其實不管是對於一個系統來講,我們將系統上面attach一個東西,我們最關心的是,我能不能還原,有能力再恢復回去。你增加的一些東西,你增加Sandbox和這些模塊之後,對我的系統到底它是怎麼去作用上去的,它在哪裡發生了形變,它的怎麼作用上去的,我系統還能不能還原。

這樣的話,其實這幅圖就是表現的是這樣的一件事情,我們先看一下我們的形變發生在哪裡,對JVM已經加載的類進行過濾(過濾器由Module告知sandbox),找到需要形變的類。拿到我要形變的類之後,他會通過一個形變通道,通過這個形變通道,形變通道上面都有哪些事情,都有哪些形變,就是由我們Sandbox加載的各個Module來決定的。

這邊相當於是一個事件監聽表,這個Module對這個類發生了一次形變。如果我新增加一個Module會怎麼樣,所有的類會重新過濾一次,對Module指定重新加載形變。如果我減少一個Module。同樣的,需要先過濾出Module指定的類,然後進行形變。這樣的話,從這個上面我們可以看到,如果我把Sandbox上面所有的模塊全部卸載掉之後,整個通道就是沒有形變的,沒有形變的話,就是一個class而變成這個數,然後再變成一個class,其實它就是沒有形變,整個代碼其實也就還原了。

在使用Sandbox過程中,如果你只掛載Sandbox,本身對你原碼是沒有影響的,如果你在Sandbox基礎上掛載了Module,Module決定了你影響了哪些類和哪些方法。當你把一個Module卸載掉之後,整個形變也就消失了,這是動態可插拔來完成的。

如上圖,這是JVM-Sandbox的一個整體的架構,這個裡面比較底層就是在JVMTI架構體系上面去構建的,做了一些代碼編織的框架。我們可以對它進行方法調用的環繞編織,方法流程的幹預,方法路徑的編織,這樣的一些過程。沙箱會進行事件分發,事件監聽,事件註銷和事件的一些處理。這樣其實就完成了,我們完成了模塊的管理,上層我們會做一些模塊管理的事情。

我們看這個裡面,多出來的一塊其實這一部分,這部分就是在Sandbox裡面,它有個HTTP伺服器,它的作用是整個Sandbox掛起之後,你的模塊是需要掛載、卸載、激活、啟動這些操作時,伺服器來控制它。當時比較方便的一種方式就是HTTP企圖去控制,所以它裡面增加了HTTP的伺服器。所以你在Sandbox掛載之後,上層的模塊,其實都可以通過HTTP請求然後加以控制,去控制它的啟動、卸載和加載這樣的一些事情。

Sandbox本身是已經開源的,能夠拿到它所有的原代碼。我們希望是有更多的同學,能夠想到更多的應用場景,並且開源出來供大家使用。

本次WOT峰會講師演講稿件由51CTO採編整理,如欲了解更多,敬請登錄WWW.51CTO.COM進行查看。

【51CTO原創稿件,合作站點轉載請註明原文作者和出處為51CTO.com】

【責任編輯:

劉妮娜

TEL:(010)68476606】

點讚 0

相關焦點

  • JVM Young GC模擬觸發和日誌查看
    當對象大於10M時直接進入老年代-XX:+UseParNewGC (年輕代)使用parnew垃圾回收器-XX:+UseConcMarkSweepGC (老年代)使用cms垃圾回收器-XX:+PrintGCDetails 列印gc詳細日誌我用的idea,給運行程序配置上面的
  • JVM中的五大內存區域劃分詳解及快速掃盲
    簡單用一張圖來理解這三個的關係:3. jvm的組成成分不了解jvm的同學看到這張圖後可能會有點懵逼,不過沒關係,放這張圖只是想讓你了解jvm中有三塊內容非常重要,1.java代碼如何執行?運行java文件的大概流程想要運行java的源文件,必須要經過javac編譯器編譯成.class文件,也就是字節碼文件。然後通過jvm中的解釋器,解釋成特定機器上的機器碼。每種機器上的解釋器是不一樣的,我們經常用的也就是windows和linux系統,這也是為什麼java能夠跨平臺的原因。
  • 這一定是全網寫JVM最好的文章之一—JVM運行時數據區
    JVM標準加上實現了一大堆類庫,就組成了Java的運行時環境,也就是我們常說的JREJDK:玩過Java的小夥伴應該都用過java -jar,javac等命令吧,如果只有jvm,jre,我們代碼是寫完了,但是怎麼編譯呢?或者代碼出了問題怎麼調試呢?
  • 程式設計師每日一題-jvm裡方法和方法區、棧區的二三事
    答案是D解析又是JVM相關的,那就先上一個JAVA虛擬機運行時數據區的邏輯圖JAVA虛擬機運行時數據區的邏輯圖好,對照上圖,逐項解釋A:堆區是JVM 所管理的內存中最大的一塊。線程共享,主要是存放對象實例和數組。
  • JVM內存區域之線程私有區域
    我們來通過一段非常簡短的代碼來演示虛擬機棧的作用:當我們運行main方法,虛擬機會開啟一個線程,同時為當前線程劃分一塊內存區域作為當前線程的虛擬機棧。同時在執行每個方法的時候都會打包成一個棧幀。比如 main 開始運行,打包一個棧幀送入到虛擬機棧。
  • 詳解Spring框架的AOP機制
    下面列出的是spring-aop-5.0版本,其它版本也可以。(4)添加Spring配置文件在課程案例SpringProgram項目中,添加Spring配置文件aop.xml。aop.xml需要使用AOP命名空間,因此需要在配置文件中導入spring-aop架構,添加下面的AOP命名空間。
  • 面試中常被問的11組JVM關係,收藏了
    第8組:引用計數法和可達性分享算法的關係引用計數法給對象添加一個引用計數器,每當一個地方引用它object時計數加1,引用失去以後就減1,計數為0說明不再引用優點:實現簡單,判定效率高缺點:無法解決對象相互循環引用的問題
  • 技術乾貨|深入理解JVM字節碼執行引擎!
    另外我們說Java虛擬機的解釋引擎是基於棧的執行引擎,其中的棧指的就是操作數棧。  3、動態連接  每個棧幀都包含一個指向運行時常量池中該棧幀所屬方法的引用,持有該引用是為了支持方法調用過程中的動態連接。  4、方法返回地址  存放調用調用該方法的pc計數器的值。
  • JeecgBoot 2.4 微服務正式版發布,基於 SpringBoot 的低代碼平臺
    項目介紹JeecgBoot 是一款基於代碼生成器的低代碼平臺!
  • 基於Cortex-A9的地鐵閘機讀卡器解決方案
    地鐵閘機升級改造主要分為傳統地鐵閘機升級改造和新地鐵線路閘機普及,傳統地鐵閘機升級保持原閘機形態不變,核心變更確統一採用支持二維碼支付的地鐵閘機讀卡器替換傳統的單片機方案NFC讀卡器。  二、基於Cortex-A9核心板的地鐵閘機讀卡器解決方案  2017年地鐵閘機讀卡方式迎來全國性升級改造,由傳統的NFC讀卡升級支持銀聯及二維碼讀卡器。由於地鐵閘機存在很強的區域性,各個城市區域採取的技術方案均不統一,但是全國的技術指標確基本統一,即 「1G主頻、1G內存、4G eMMC」。
  • 地球的一半︱以基於自然的解決方案應對氣候變化
    IC  資料圖合理且充分地利用我們身邊的大自然,這種基於自然的解決方案是應對氣候變化的多種方式中有效且最具經濟效益的方法之一。而且在用低成本方式解決氣候變化引發的問題的同時,還能帶來額外的收益。近年來,基於自然的解決方案引起了廣泛關注,2019氣候行動峰會上,中國在挪威、斐濟和紐西蘭的支持下,成為了基於自然的解決方案(六個優先行動之一)的牽頭國家。自然提供的低成本解決方案基於自然的解決方案在經濟可行性上有諸多優勢。首先,可以避免不必要或過度成本支出,減少未來災害重建成本。
  • 華為基於5G微波解決方案助力勝利油田智能化升級
    為此,濟南恆達新公司攜手華為,基於華為先進的5G微波技術,以及濟南恆達新在能源領域的積累,聯合打造基於5G微波的油田智能化解決方案,實現油井視頻、傳感數據、控制數據的穩定、可靠回傳,同時結合前後端的智能化AI分析,提升油田的智能化水平。目前該方案已在中石化勝利油田東辛、孤島、勝利等多個採油廠試驗成功,收穫好評。