BTrace Java

BTrace簡介

楊凱傑 2022/04/07 15:00:00
206

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

2.https://cloud.tencent.com/developer/article/1613055

3.https://www.cnblogs.com/lnlvinso/p/11074633.html

楊凱傑