阿里巴巴正式開源自研動態非侵入AOP解決方案:JVM-Sandbox
程序員的 8 點技術早餐
作者|徐冬晨
編輯|小智
開源改變世界!
寫在前面
隨著軟體部署規模的擴大,系統的功能的細化,系統間耦合度和鏈路複雜度不斷加強。若要繼續保持現規模系統的穩定性,需要實現並完善監控體系、故障定位分析、流量錄製回放、強弱依賴檢測、故障演練等支撐工具平台。出於對伺服器規模和業務穩定性的考量,這些配套工具平台要具備對目標應用具有無侵入、實時生效、動態可插拔的特點。
要實現這些,多少都會觸及到一塊底層技術——動態位元組碼增強。如果每個工具都自己實現一套位元組碼增強邏輯,前期實現的門檻與後期維護成本高,且不同工具間相互影響造成不可預知的風險。如何屏蔽位元組碼增強技術的高門檻,降低研發運維成本,同時又能支持上層多個工具平台功能的快速實現和動態管理,成為阿里集團的目標。從去年開始潛心修行,創新的研發了一套實時無侵入的位元組碼增強框架。
於是 JVM-Sandbox 誕生了!
應用場景
JVM-Sandbox 的目標群體
Btrace 好強大,也曾技癢想做一個更便捷、更適合自己的問題定位工具,既可支持線上鏈路監控排查,也可支持單機版問題定位。
有時候突然一個問題反饋上來,需要入參才能完成定位,但恰恰沒有任何日誌,甚至出現在別人的代碼里,好想開發一個工具可以根據需要動態添加日誌,最好還能按照業務 ID 進行過濾。
系統間的異常模擬可以使用的工具很多,可是系統內的異常模擬怎麼辦,加開關或是用 AOP 在開發系統中實現,好想開發一個更優雅的異常模擬工具,既能模擬系統間的異常,又能模擬系統內的異常。
好想獲取行調用鏈路數據,可以用它識別場景、覆蓋率統計等等,覆蓋率統計工具不能原生支持,統計鏈路數據不準確。想自己開發一個工具獲取行鏈路數據。
我想開發錄製回放、故障模擬、動態日誌、行鏈路獲取等等工具,就算我開發完成了,這些工具底層實現原理相同,同時使用,要怎麼消除這些工具之間的影響,怎麼保證這些工具動態載入,怎麼保證動態載入 / 卸載之後不會影響其他工具,怎麼保證在工具有問題的時候,快速消除影響,代碼還原。
如果你有以上訴求,那麼你就是 JVM-Sandbox 的潛在客戶。JVM-Sandbox 提供動態增強類你所指定的類,獲取你想要的參數和行信息;提供動態可插拔容器,管理基於 JVM-Sandbox 的模塊。
JVM-Sandbox 能做什麼?
在 JVM-Sandbox(以下簡稱沙箱)的世界觀中,任何一個 Java 方法的調用都可以分解為、和三個環節,由此在三個環節上引申出對應環節的和。不僅如此還有事件,可以完成代碼行的記錄。
基於、和三個環節事件以及事件,可以完成很多類 AOP 的操作。
可以感知和改變方法調用的入參
可以感知和改變方法調用返回值和拋出的異常
可以感知一個請求按順序執行了哪些行
可以改變方法執行的流程
在方法體執行之前直接返回自定義結果對象,原有方法代碼將不會被執行
在方法體返回之前重新構造新的結果對象,甚至可以改變為拋出異常
在方法體拋出異常之後重新拋出新的異常,甚至可以改變為正常返回
JVM-Sandbox 都有哪些可能的應用場景
線上故障定位
線上系統流控
線上故障模擬
方法請求錄製和結果回放
動態日誌列印
安全信息監測和脫敏
行鏈路計算和覆蓋率統計
JVM 沙箱還能幫助你做很多很多,取決於你的腦洞有多大了。
JVM-Sandbox 在阿里集團的應用
線上故障演練
17 年故障演練平台在 JVM-Sandbox 基礎上僅耗時 1 周即完成故障注入部分的系統重構。重構後的系統在掛載效率和掛載成功率方面有了明顯的提升,極大的縮短的故障演練的時間,演練效率提升了數十倍。基於 JVM-Sandbox 改造後的故障演練平台,通用性強,所有基於 JVM 啟動的系統均支持,極大的拓展了故障演練的範圍,故障演練已達到集團級部署。
與 16 年故障演練數據對比,17 年的故障演練平台,覆蓋 BU 提升了 1.6 倍,覆蓋應用提升了 5 倍,覆蓋場景提升了 37 倍。
依賴檢測
17 年強弱依賴自動化檢測平台誕生。它提供了依賴檢測、強弱分析、依賴掃描、故障注入等多種能力,底層能力基於 JVM-Sandbox 在 1 周內完成功能開發。利用其模塊容器的特性,將前人開發的模塊與新增模塊一起掛載共同工作,完成平台功能。
強弱依賴梳理方面,承載了淘寶的系統強弱依賴梳理工作,260+ 個應用一鍵接入系統,並實現了 0 人工成本的自動化、智能化梳理。
服務端錄製隔離回放機制
在 JVM-Sandbox 基礎上開發了一個 SS 模塊,相當於一個錄音機 + 回放機, 在調用中間件的時候, 順序錄製下了我們的中間件請求, 並且存儲這份『磁帶』到伺服器上。當我們需要隔離回放的時候, 將這份『磁帶』找到, 並且在需要的時候直接從『磁帶』讀取, 並不需要真實地請求我們的中間件, 這樣就保證了我們的讀、寫介面也能做到可重複使用,從而實現服務端的隔離回放。
線上錄製隔離回放不僅極大的縮短的業務回歸的耗時,把業務測試同學從繁瑣的數據準備和介面自動化腳本的編寫過程中解放出來,而且極大的拓展了覆蓋範圍,使回歸的範圍更貼近用戶,且場景更豐富。
精準回歸
服務端錄製隔離回放機制誕生之後,雖然有效的提升了覆蓋範圍,降低了自動化腳本的人工投入,但是也帶來了新的問題。線上錄製的場景是海量的,單個系統都可以達到萬級、十萬級甚至百萬級別的錄製,這些錄製的場景中,存在大量的重複場景,如何識別重複場景,實現有效、精準的回放,成為新的待解決問題。
17 年在 JVM-Sandbox 的基礎上,利用 LineEvnet 實現了行鏈路識別和標記,有效的提升了回放的精準度和效率。
JVM-Sandbox 在阿里集團已經實現全網部署,在其上載入不同的模塊實現了不同的功能,每個功能根據 BU 和應用的需要進行載入:
強弱依賴檢測功能:覆蓋淘寶、天貓、業務平台、菜鳥、飛豬、ICBU、CBU 等 7 個 BU,240+ 個應用;
線上故障演練功能:覆蓋集團客戶體驗事業群、淘寶網、雲零售事業部、天貓、業務平台、飛豬、菜鳥、釘釘、阿里健康、CBU、集團安全、支付寶等 16 個 BU,391 個應用;
服務端錄製回放:覆蓋淘寶網、釘釘 2 個 BU;
精準回歸:覆蓋淘寶網、業務平台、釘釘 3 個 BU。
通過上邊的事例,想必大家對 JVM-Sandbox 是什麼,核心功能是什麼,還能做哪些事情,以及是否可以為阿里以外的同學提供服務等問題更感興趣了,下面我們著重介紹這部分內容。
JVM-Sandbox
技術背景
故障演練、強弱依賴檢測、錄製回放、精準回歸,要解決這些問題本質就是如何完成 java 方法的環繞管控和運行時行鏈路的獲取,即 AOP 框架的解決方案。目前常用 AOP 框架的解決方案有兩種:proxy 和埋點。proxy 的優點在於已實現了統一的 API,減少了重複投入,但是不能實時生效,需要系統編譯重啟。埋點的優點在於動態生效靈活度高,但是沒有統一 API。
要快速解決上邊的四個問題,我們需要的 AOP 解決方案必須具備兩個特性:
動態可插拔,即實現埋點方式的統一的 API
無侵入性,即解決 JVM 類隔離的問題
基於以上需求,我們研發了 JVM-Sandbox。
JVM-Sandbox 的核心功能
JVM-Sandbox 由純 Java 編碼完成,基於 JVMTI 技術規範,為觀察和改變代碼運行結果提供了即插即用模塊介面的容器,提供核心功能:
使用埋點技術提供統一的 API,來實現無需重啟的 AOP 解決方案
使用容器完成 JVM 類隔離,來解決侵入性問題
提供容器管理機制,來完成各種容器的管理
JVM—Sandbox 的核心事件模型
BEFORE、RETURN 和 THROWS 三個環節事件的正常流轉和干預流轉
隔離和通訊
隔離:
沙箱通過自定義的破壞了雙親委派的約定,實現了和觀察應用的類隔離。所以不用擔心載入沙箱會引起應用的類污染、衝突。
沙箱各模塊之間類通過實現了各自的獨立,達到模塊之間、模塊和沙箱之間、模塊和應用之間互不干擾。
通訊
通過向 Bootstrap ClassLoader 中注入 Spy 類,完成觀察應用與 JVM-Sandbox 的通訊
JVM-Sandbox 會將事件分發給各個 Module,完成 JVM-Sandbox 與 Module 之間的通訊
模塊動態管理
事件監控表,完成模塊的管理
trasform 方法形變原生位元組碼
代碼編織
插入 Spy 類到位元組碼中,Spy 方法中反射調用 JVM-Sandbox 的方法。
以 BeforeEvent 為例,進行代碼編織展示。
整體架構
沙箱一共由三大核心功能組件構成
代碼編織組件
負責完成預設代碼的重寫和生效
事件處理分發組件
負責完成事件的分發和方法流控控制的執行
模塊管理組件
負責控制和管理沙箱的各個模塊
沙箱的底層提供了一個 HTTP-SERVER(Jetty),通過 HTTP 協議完成和沙箱的控制交互,同時也給各個模塊提供了基於 HttpServlet 和 WebSocket 規範的 API,各模塊可以復用沙箱完成各自模塊的控制與交互。
開源和共建
1、已開源,尋求更多的同學一起完善 JVM-Sandbox 的功能。Github 地址:
https://github.com/alibaba/JVM-Sandbox
2、希望有同學和我們一起共同完善 JVM-Sandbox 的功能;
3、希望更多的同學想到跟多的應用場景,並能開源出來供大家使用。
綜上,JVM-Sandbox 是一個純 java 編寫的 AOP 解決方案。它為研發人員提供了一個快速實現位元組碼增強工具的平台。他的模塊管理功能可以最大限度的復用模塊、協同合作,減少重複投入。
隨著 JVM-Sandbox 的開源,我們期待更多的人加入到功能擴張和優化上,使其適配更多的開源中間件和 JVM。
希望有更多的同學,發揮其聰明才智,開發更多、更好的上層模塊,提供給自己和其他人的人使用。也希望能夠利用好已有的模塊,組裝出新的工具平台和應用場景。
JVM-Sandbox 建設和應用期待大家共同建設。
作者介紹
徐冬晨,花名鸞伽,阿里巴巴測試開發專家,2010年加入阿里巴巴,先後負責商品平台、交易平台、手機淘寶的測試開發工作,一直致力用技術解決業務測試中遇到的各種問題,提升測試效率和系統穩定性。連續參與6年天貓雙十一,在服務端穩定性方面,經驗豐富、見解獨到。
今日薦文


TAG:InfoQ |