BTrace簡介
Btrace是什麼?
BTrace是一個動態安全的Java追蹤工具,它通過向運行中的Java程式植入字節碼(bytecode)文件,來對運行中的 Java 程式熱更新,方便的獲取程式運行時的數據信息,並且保證自己的消耗特別小,大部分情況下不會影響Java程式的性能。
Btraces能做什麼?
舉例來說,今天在生產環境的時候,如果要發現某個方法特別慢但又沒記錄相關log的時候,一般處理方式為
(1)調整程式加上log
(2)重新佈署
(3)重啟服務
(4)查看log
BTrace的出現就是為了解決這問題,他可以通過自己編寫好的腳本,然後直接把程式注入到線上環境,不需上面的調整步驟,可以快速方便的查找問題
由於Btrace會把腳本邏輯直接侵入到運行的代碼中,所以在使用上做很多限制:
1.不能創建物件
2.不能使用陣列
3.不能拋出或捕獲異常
4.不能使用循環
5.不能使用synchronized關鍵字
6.屬性和方法必須使用static修飾
根據官方聲明,不恰當的使用BTrace可能導致JVM崩潰,如在BTrace腳本使用錯誤的class文件,所以在上生產環境之前,務必在本地充分的驗證腳本的正確性。
以下是 BTrace 的一些典型應用場景:
(1)服務慢,能找出慢在哪一步,哪個函數
(2)誰調用了System.gc(),調用棧如何?
(3)誰構造了一個超大的 ArrayList?
(4)什麼樣的傳入參數或物件屬性,導致拋出了這個異常?或進入了這個處理分支?
BTrace使用範例
首先先到官網下載最新版本 => https://github.com/btraceio/btrace/releases
這邊使用的是2.2.2版本,maven開發
(1)引入下列依賴
<dependencies>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-agent</artifactId>
<version>2.2.2</version>
<type>jar</type>
<scope>system</scope>
<systemPath>C:\software\btrace-v2.2.2-bin\libs\btrace-agent.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-boot</artifactId>
<version>2.2.2</version>
<type>jar</type>
<scope>system</scope>
<systemPath>C:\software\btrace-v2.2.2-bin\libs\btrace-boot.jar</systemPath>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-client</artifactId>
<version>2.2.2</version>
<type>jar</type>
<scope>system</scope>
<systemPath>C:\software\btrace-v2.2.2-bin\libs\btrace-client.jar</systemPath>
</dependency>
</dependencies>
2.寫一支BtraceCase.java來模擬線上在跑的java server程式
啟動後會不斷隨機每隔一段時間後跑完add function
import java.util.Random;
public class BtraceCase {
public static Random random = new Random();
public static void main(String[] args) throws Exception {
new BtraceCase().run();
}
public void run() throws Exception {
while (true) {
add(random.nextInt(10), random.nextInt(10));
}
}
public int add(int a, int b) throws Exception {
Thread.sleep(random.nextInt(10) * 100);
return a + b;
}
}
3.寫一支BTrace的腳本來監控上面BtraceCase中的add方法的執行時間,輸入輸出參數
import org.openjdk.btrace.core.BTraceUtils;
import org.openjdk.btrace.core.annotations.*;
@BTrace//表示這是一個BTrace跟蹤腳本
public class Hello {
@OnMethod(clazz = "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);
}
}
4.進入剛剛下載好的BTrace下的bin資料夾,並將btrace權限調整成777
5.建立一個資料夾將剛剛寫好的BtraceCase.java跟Hello.java放入編譯並執行
6.開啟另一個視窗輸入jsp查看運行中的pid並執行 ./btrace <pid> <Hello.java腳本位置>
可以看到BtraceCase每次執行add方法都會打印出相關訊息,過程中我們完全沒有去調整BtraceCase.java程式
這邊只是簡單示範了基本的使用方式,還有其他很多的註解跟參數,實際遇到什麼問題去查詢官網說明即可 => https://github.com/btraceio/btrace/wiki
參考資料:
1.https://github.com/btraceio/btrace