Categories
程式開發

有贊雲應用遠程調試工具


一、背景和簡介

1.1 背景

電商云有容器應用場景下,第三方外部開發者的應用是託管在我們有贊雲平台的容器中的,出於安全以及整個平台穩定性的要求,應用容器執行環境對外部開發者用戶都應該是透明黑盒的。而電商雲環境下容器應用的運行會直接依賴於電商雲平台所提供Apollo、rds、kvds等各種底層中間件能力,這就導致外部開發者想要實現應用代碼的本地調試幾乎是不現實的。同時考慮到復雜的網絡環境和安全穩定性的要求,平台也不可能開放用戶直接連到線上容器應用中利用JVM提供的基於JDWP的遠程調試功能。外部開發者強烈的調試需求要求我們平台給外部開發者提供一種在電商雲環境下的應用的調試能力。

1.2 簡介

有贊雲應用遠程調試工具是一種不侵入應用代碼、不打斷應用代碼執行、盡可能少的影響代碼執行效率的前提下,實現線上應用近似本地調試的體驗的調試工具。

總體實現思路是通過java字節碼增強技術對開發者指定的代碼類包進行精準增強,在滿足設定的命中條件時對應用程序執行過程進行錄製生成快照,然後用戶使用平台提供的IDE回放插件就登錄下載快照文件進行本地回放,達到近似本地調試的體驗。

二、整體架構

2.1 架構圖

有贊雲應用遠程調試工具 1

上圖簡要描述了工具的整體架構:

  • IDE插件主要有狀態管理,錄製文件管理等模塊,通過輪訓狀態來執行下載文件和回放操作;
  • record-server是的作用是中樞調度,主要包含三大塊:錄製管理,沙箱調度,數據管理。
  • 錄製管理:管理有贊雲應用容器中的沙箱和錄製狀態;以及拆分IDE插件的指令分發給沙箱調度器和數據管理器
  • 沙箱調度:提供有贊雲應用容器中可執行的沙箱指令;
  • 數據管理:管理請求錄製快照數據;
  • 有贊雲環境和有贊雲應用容器之間有安全策略,限制請求只能有贊雲調用有贊雲應用容器的服務;
  • 在有贊雲應用容器環境中的數據和狀態流轉使用的是kafka和flink

2.2 設計上的考量

為了達到項目的總體目標(不侵入應用代碼、不打斷應用執行、盡可能少的性能損耗、合理的錄製數據量),我們項目一期設計上做了一些權衡:

  1. 錄製結束後恢復:錄製時按需對應用代碼字節碼增強,錄製結束後進行恢復;
  2. 錄製範圍:應用代碼字節碼增強後對代碼執行效率影響是很大的,考慮到大部分用戶只關注自己實現部分的業務代碼邏輯的調試,對一些java標準類庫、第三方包等的深入調試需求很低,所以我們僅對指定包路徑下的類代碼進行增強錄製快照;
  3. 錄製場景:完整錄製整個應用的執行快照的話,錄製性能損耗高、錄製數據量大,應對多線程錄製並發問題,複雜度高等問題,但大部分應用場景更多的是關心單個線程執行鏈路的正確性調試,所以我們簡化設計——對單線程中某個方法運行情況進行錄製;
  4. 錄製命中條件:一期盡量簡化錄製條件避免無冗餘重複錄製,具體設計為:設置錄製命中入口函數,啟動錄製後,代碼執行第一次到達入口函數即為命中,當前線程即進入錄製狀態,錄製並保存該線程的運行時快照信息,當前線程從入口函數返回即為錄製結束;
  5. 行錄製優化:盡量減少無效的行錄製(僅對發生賦值操作或發生函數調用後的行進行錄製);
  6. 快照數據優化:僅對類對像中get方法和public 屬性序列化生成快照;
  7. 錄製過程異步化:錄製過程中代碼增強與反增強過程、快照數據持久化、錄製組件初始化與清理等都採用異步化實現。

三、IDEA插件介紹

3.1 插件界面展示及功能介紹

有贊雲應用遠程調試工具 2

插件目前支持的功能包括:

  • 權限管理:通過手機號和token進行驗權;
  • 有贊雲遠程調試啟動器:打開有贊雲應用代碼,配置入口類和入口方法,開始調試,然後出發接口調用,錄製結束後自動跳到入口類和方法的第一行,然後就可以進行無阻塞的快照形式的調試,一次錄製多次調試;

3.2 插件運行流程

有贊雲應用遠程調試工具 3

3.3 構建文件索引

有贊雲應用遠程調試工具 4

目前索引內容是用內存實現的,未來會支持本地文件檢索。下面簡單介紹下這樣設計的原因:

  • 調試步驟包括resume、stepOver、stepInto、stepOut、點擊調用棧跳轉,需要根據每種步驟計算出對應的行快照信息並展示;
  • 方法信息:計算出對應行快照信息之後獲取方法的相關信息展示到調試欄;
  • 類對應的行快照:用來在點擊調用棧跳轉時根據類名和行號定位行快照的;
  • 方法調用對應行快照:用來stepOver時快速找到下一行使用;
  • 所有行快照:用來stepInto快速定位下一個錄製行快照使用;
  • pos:記錄當前正在調試的位置;

四、應用方法執行錄製

應用方法執行錄製是基於阿里開源的jvm-sandbox進行定制後實現的,主要做的事情包括:

  • 增強了jvm-sandbox的內核,支持行調用通知獲取局部變量;
  • 增加了sandbox錄製的插件,用來監聽事件來進行數據處理和持久化;

4.1 Jvm-sandbox內核增強

有贊雲應用遠程調試工具 5

上面是代碼增強邏輯的偽代碼呈現,上面例子中真實增強的代碼實際反彙編後如下:

有贊雲應用遠程調試工具 6

與開源版本的區別

有贊雲應用遠程調試工具 7

擴展內容:

  1. Spy.spyMethodOnCallBeforeExt,Spy.spyMethodOnCallReturnExt,Spy.spyMethodOnCallThrowsExt擴展了參數列表,用來未來擴展
  2. Spy.spyMethodOnLineExt:行調用前通知,用來錄製當前對象和方法參數和本地變量(本次主要使用的擴展)

4.2 沙箱錄製模塊加載過程

有贊雲應用遠程調試工具 8

4.3 局部變量表分析

在進行字節碼增強之前會通過ClassMetaVisitor先進行一次字節碼分析拿到局部變量表。流程如下:

有贊雲應用遠程調試工具 9

  • appendLabel:記錄label信息;
  • appendLineNumber:記錄行號信息,並記錄行號和label對應關係;
  • appendLocalVariable:記錄局部變量信息和對應的開始和結束的label
  • updateLocalVariableLine:根據開始結束的label計算本地變量的作用的行號範圍,一般情況下查找行號的規則是計算當前label的行號信息,當前label沒有行號信息時開始label向後找,結束label向前找
  • updateLocalVariableScope:優化局部變量表的有效範圍,防止局部變量表有復用的情況時存在兩個複用的局部變量存在有效行區間存在覆蓋的情況
  • registerMethodMeta:存儲分析好的局部變量表

4.4 錄製過程解析(以行錄製為例)

有贊雲應用遠程調試工具 10

  • beforeLineExt:獲取到計算後的局部變量表,然後獲取對應變量值並持久化

4.5 錄製數據模型

有贊雲應用遠程調試工具 11

五、沙箱環境管理

有贊雲應用遠程調試工具 12

上圖簡述了沙箱的安裝和卸載的管理過程;其中record-server不能直接和有贊雲應用容器交互,必須通過ops中轉;

六、未來規劃

  1. 豐富各種錄製場景應對複雜問題調試;
  2. 提高錄製性能;目前在開啟錄製之後代碼運行速度很慢,可能會造成接口調用超時
  3. 遠程調試+熱部署,邊開發邊調試更加極致的開發體驗(DCEVM + HotSwapAgent );

本文轉載自公眾號有贊coder(ID:youzan_coder)。

原文鏈接

https://mp.weixin.qq.com/s/EGyM88I22HLbIOCDVGvxHA