BTrace 是什麼?
BTrace 是一個動态安全的 Java 追蹤工具,它通過向運作中的 Java 程式植入位元組碼檔案,來對運作中的 Java 程式熱更新,友善的擷取程式運作時的資料資訊,并且,保證自己的消耗特别小,大部分情況下不會影響 Java 程式的性能。
BTrace 能幹什麼?
相信每一位開發都或多或少的幹過這檔子事:為了解決線上的一個 bug,不得不在代碼中列印下入參、出參資料,然後再重新開機伺服器,觀察日志。BTrace 的出現就是為了解決這類事宜,BTrace 的最大好處,是可以通過自己編寫的腳本,擷取應用的一切調用資訊,而不需要不斷的修改代碼,然後重新開機應用。
以下是 BTrace 的一些典型應用場景:
- 服務慢,能找出慢在哪一步,哪個函數裡麼?
- 誰調用了System.gc(),調用棧如何?
- 誰構造了一個超大的 ArrayList?
- 什麼樣的入參或對象屬性,導緻抛出了這個異常?或進入了這個處理分支?
BTrace 快速開始
下載下傳最新的 BTrace releases 版本:https://github.com/btraceio/btrace/releases
解壓檔案夾,在 <BTRACE_HOME>/bin 目錄下主要有兩個指令:一個是 btrace,一個是 btracec。
btrace
BTRACE_HOME/bin/btrace PID <trace_script>
btrace 将通過 JVM Attach API 連接配接到
的 java 應用程式,然後把腳本綁定到應用程序,進行 AOP 式的代碼植入。
btracec
BTRACE_HOME/bin/btracec <trace_script>
類似于 javac,btracec 指令是用來預編譯腳本的,以此校驗腳本文法的正确性,要不然等運作到線上才發現寫錯就尴尬了。
BTrace 腳本
寫到這裡,唯一能阻礙我們繼續下去的,就是怎麼寫 BTrace 腳本了。
首先,推薦在內建工具(IDEA、Eclipse)中編寫 BTrace 腳本,引入 BTrace 的依賴:
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-agent</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-agent.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-boot</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-boot.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-client</artifactId>
<version>1.2.3</version>
<type>jar</type>
<scope>system</scope>
<systemPath>D:\btace\libs\btrace-client.jar</systemPath>
</dependency>
先來看一個簡單的 Demo 示例:
@BTrace//表示這是一個BTrace跟蹤腳本
public class Hello {
@OnMethod(clazz = "org.jvm.demo.chapter4.btrace.BtraceCase", // 全類名
method = "add", // 方法名
location = @Location(Kind.RETURN) // 表示跟蹤某個類的某個方法,位置為方法傳回處
)
public static void run(@Self Object self, int a, int b, // 入參,按順序定義
@Return int result, // 出參
@Duration long time // 方法耗時
) {
BTraceUtils.print("列印入參, a = " + a + ",b=" + b);
BTraceUtils.print("列印出參, result = " + result);
BTraceUtils.print("列印耗時,time = " + time);
}
}
btrace.bat 4284 src/main/java/org/jvm/demo/chapter4/btrace/Hello.java
BTrace 主要有兩類注解需要學習,一類是
探測方法的注解,像上面的 @OnMethod 注解,類似的還有 @OnTimer、@OnError、@OnExit、@OnEvent、@OnLowMemory、@OnProbe 等等;另一類是
探測方法參數的注解,像上面的 @Return、@Duration、@Self,類似的還有 @ProbeMethodName、@ProbeClassName、@TargetInstance、@TargetMethodOrField 等等
本文不過分說明 BTrace 的文法,私以為平常遇到什麼樣的業務場景,邊學邊用就是了,以下是官方的一些 BTrace 資料:
- BTrace Github Wiki
- BTrace User's Guide
由于 BTrace 的安全和性能考慮,一般情況下不允許在探查方法中調用 BTraceUtils 以外的其它方法,但可使用 unsafe 模式。
BTrace 植入過的代碼,會一直在,直到應用重新開機為止。是以即使 Btrace 退出了,業務函數每次執行時都會多出一次 Btrace 是否 Attach 狀态的判斷。
為了保證程式的安全,BTrace對編寫的腳本進行了一些限制,比如不允許在腳本中建立對象,不允許在腳本中抛出異常等,更詳細的限制請參考 BTrace 使用限制。
推薦閱讀:
- Btrace入門到熟練小工完全指南
- 如何在生産環境使用Btrace進行調試
- BTrace使用小結