BTrace簡單使用

BTrace:Byte trace,通過動態字節碼將跟蹤操作代碼插入到正在運行的Java程序的類中。
簡單來說,就是通過 instrument + asm,對正在運行中的類,進行動態增強。使用過Jrebel 的對此可能非常熟悉,原理類似。

使用場景

基於此,btrace 被用於線上排查問題,追蹤bug。最常用的就是跟VisualVM 一起用來排查問題。
 

概念

探測點

 

限制

爲保證對線上代碼沒有過多侵入,同時也沒有副作用(比如引起了異常、修改變量、中斷代碼邏輯等),對btrace做了一下限制:

不能創建對象
不能創建數組
不能拋出和捕獲異常
不能調用任何對象方法和靜態方法
不能給目標程序中的類靜態屬性和對象的屬性進行賦值
不能有外部、內部和嵌套類
不能有同步塊和同步方法
不能有循環(for, while, do..while)
不能繼承任何的類
不能實現接口
不能包含assert斷言語句

 

使用

它的使用很簡單,有兩個方式;與visualVM一起使用;命令行操作腳本。

與VisualVM配合使用

VisualVM一般用來查看java服務運行時內存的。

待整理

操作腳本

有三步:

1.寫腳本

這個可以新建個項目,引入這些包

dependencies {
    compile group: 'com.sun.tools.btrace', name: 'btrace-agent', version: '1.2.3'
    compile group: 'com.sun.tools.btrace', name: 'btrace-client', version: '1.2.3'
    compile group: 'com.sun.tools.btrace', name: 'btrace-boot', version: '1.2.3'
}

代碼也簡單:

@BTrace(unsafe = true)
public class PrinterTest {

    @OnMethod(
            clazz = "com.hust.service.MyService", method = "print", location = @Location(Kind.ENTRY)
    )
    public static void called(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
        BTraceUtils.printArray(args);
        BTraceUtils.println("className: " + pcn);
        BTraceUtils.println("MethodName: " + pmn);
        BTraceUtils.println();
    }
}

指定方法和探測點。

 

2.本地安裝

官網下載,解壓到本地,然後加環境變量 BTRACE_HOME 即可

BTRACE_HOME=/data/btrace

另外,btrace運行需要有JAVA_HOME ,沒有的話可以簡單配置下

安裝java後查看java_home:

/usr/libexec/java_home -V

我的電腦上是

/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home

然後加JAVA_HOME 到環境變量

cd ~
vim .bash_profile

在家目錄下,編輯 該文件,如果沒有則創建:

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home
CLASSPAHT=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

PATH=$JAVA_HOME/bin:$PATH:
export JAVA_HOME
export CLASSPATH

export PATH

編輯後保存退出。

爲了使修改立刻生效,執行:

source .bash_profile

3.跟蹤

先找到java服務器的pid,比如:

ps -ef | grep name

找到後就可以執行以下命令去追蹤了:

btrace pid trace_script

其中pid是你要追蹤的java服務進程,trace_script 是第一步寫代碼編譯後的腳本,即 .class 文件

 

注意事項

BTrace 腳本可以被用來修改線上的代碼,要注意的是被修改的字節碼不會被還原。因爲增強類被類類加載器加載到方法區了,但是沒有卸載類的方式,增強類會一直留在虛擬機裏,直到JVM重啓。

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章