Btrace 是一個安全,可以動態跟蹤 java 程式的一種工具。他的操作不會對原有 java 進程產生影響,不用關閉正在啟動並執行 java 進程,也不會修改 java 進程中的邏輯和資料。因此,也就成為我們線上跟蹤生產代碼的有力工具!
之前 Btrace 只是聽說過,但還沒有具體的用到。最近在排查線上問題的時候,使用了 Btrace ,發現 Btrace 真是在關鍵時候的利器。
Btrace 是一個安全,可以動態跟蹤 java 程式的一種工具。
他的操作不會對原有 java 進程產生影響,不用關閉正在啟動並執行 java 進程,也不會修改 java 進程中的邏輯和資料。
因此,也就成為我們線上跟蹤生產代碼的有力工具!
Btrace 的指令碼編寫也非常簡單:和寫 Java 代碼一樣的,因此對於我們,學習的曲線幾乎是平坦的。
下面就分享一下 Btrace 的一些用法:
如何使用 Btrace
基本用法: trace
其中, btrace 是在 btrace 下載包中的命令 , pid 是 JVM 的進程 id , btrace-script 是編寫的 btrace 指令碼。
Btrace 中的一些概念
Probe Point : 關注點。就是我們要關注應用程式中要執行的“地方”,或者是一些“事件”的發生。
Trace Action : 就是觸發了 probe point 的時候,我們所要執行的動作。
Action Methods :我們的 trace action 都是寫在某個類的靜態方法中的,這個靜態方法,就是 action method 。
Btrace 中的一些限制:
Btrace 的初衷是要“跟蹤代碼”,而不是修改代碼,因此他要保證我們注入的指令碼,是安全的,對應用程式來說是“唯讀”的。也就是說不能修改應用程式的代碼或者資料。因此 Btrace 中有一些限制,主要有:
不能建立對象
不能拋異常
不能 catch 異常
不能調用執行個體方法和靜態方法。只能調用 Btrace 提供的 com.sun.btrace.BTraceUtils 中的方法和自己在指令碼中定義的方法。
不能有迴圈
不能有斷言
……
初看起來,好像限制蠻多的。不過, com.sun.btrace.BTraceUtils 提供的方法很多,足夠我們來“跟蹤”代碼了。而且,這些限制也是必要的,因為我們只是到那個 JVM 去看看,看看而已。
一個簡單的 Btrace 指令碼例子,其實就是 Java 代碼
其中:
其中類名需要加上 @Btrace 的注釋,以表示是 Btrace 指令碼
OnMethod 表示一個 probe point ,這個就表示當執行到 java.awt.Component 這個類的 方法(這個是 Component 的構建方法)時,就觸發 func 方法。
@Self 表示這個被執行個體化的 Component 的引用
@OnTimer 表示事件(通過時間)觸發的 probe point ,每隔 2 秒觸發一次
相信程式不用做過多解釋,大家都知道,終端將會列印出從跟蹤開始, Component 被執行個體化的個數。
支援的跟蹤類型
Btrace 支援的跟蹤類型有很多了,包括可以跟蹤:
跟蹤到某個執行個體方法的觸發
跟蹤到某個介面方法的觸發
跟蹤到觸發方法的參數,傳回值
可以將當前觸發的線程堆棧列印出來
設定還可以跟蹤某個方法中的哪一行代碼被執行到
Btrace 的 User Guide
http://kenai.com/projects/btrace/pages/UserGuide
關於 Btrace 的原理
詳情可見: http://victorzhzh.javaeye.com/blog/965789
什麼時候用 Btrace
雖然 Btrace 在關鍵時候能起到迅速排查問題的作用,但我個人感覺,這還是不到萬不得已才使用的好。
首先,我們代碼上線前,應該充分 review ,充分和相關方進行溝通,以避免不必要的問題發生。
其次,我們應該養成記 log 的良好習慣。遇到問題,如果有相關日誌可以排查,是最方便的,同時,也是最安全,成本最低的一種排查方法。
最後,我們可以結合 btrace 和 jdk 內建的 tool 來排查問題,比如 jstack , jstat 等等,快速的定位問題。