不久,該工具允許注入跟蹤點,而無需在運行時重新啟動或重新配置Java應用程序。 而且,盡管有多種方法可以做到這一點,但我今天要討論的方法是使用標準JDK捆綁包中的JVisualVM工具。
太酷了, BTrace本身使用Java語言定義注入跟蹤點。 如果您曾經進行過面向方面的編程(AOP),則該方法看起來非常熟悉。
因此,讓我們開始一個問題:我們有一個使用NoSQL數據庫之一(例如,讓它成為MongoDB)的應用程序,突然開始出現明顯的性能下降。 開發人員懷疑應用程序運行過多的查詢或更新,但不能自信地說。 BTrace在這里可以提供幫助。
首先,讓我們運行JVisualVM并安裝BTrace插件:
JVisualVM應該重新啟動以使插件出現。 現在,當我們的應用程序啟動并運行時,讓我們在JVisualVM應用程序樹中右鍵單擊它:

將出現以下非常直觀的BTrace編輯器(帶有簡單的工具欄):
在這里可以定義跟蹤工具并將其動態注入正在運行的應用程序中。 BTrace有一個非常豐富的模型來定義應該精確跟蹤的內容:方法,構造函數,方法返回,錯誤等。 它還支持開箱即用的聚合,因此在應用程序運行時很容易收集大量指標。 對于我們的問題,我們想查看與MongoDB相關的哪些方法正在執行。
當我的應用程序使用Spring Data MongoDB時 ,我對應用程序正在調用org.springframework.data.mongodb.core.MongoOperations接口的任何實現的方法以及每次調用需要多長時間感興趣。 所以我定義了一個非常簡單的BTrace腳本:
import com.sun.btrace.*;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;@BTrace
public class TracingScript {@TLS private static String method;@OnMethod(clazz = '+org.springframework.data.mongodb.core.MongoOperations', method = '/.*/')public static void onMongo( @ProbeClassName String className, @ProbeMethodName String probeMethod, AnyType[] args ) {method = strcat( strcat( className, '::' ), probeMethod );}@OnMethod(clazz = '+org.springframework.data.mongodb.core.MongoOperations', method = '/.*/', location = @Location( Kind.RETURN ) )public static void onMongoReturn( @Duration long duration ) {println( strcat( strcat( strcat( strcat( 'Method ', method ), ' executed in ' ), str( duration / 1000 ) ), 'ms' ) );}
}
讓我簡要解釋一下我在做什么。 基本上,我想知道何時調用org.springframework.data.mongodb.core.MongoOperations的任何實現的任何方法( onMongo標記)和調用持續時間( onMongoReturn依次標記)。 線程局部變量方法保存完整的合格方法名稱(帶有類),而由于使用了有用的BTrace預定義注釋, duration參數保存了方法執行時間(以納秒為單位)。 盡管它是純Java,但BTrace僅允許使用Java類的一小部分。 這不是問題,因為com.sun.btrace.BTraceUtils類提供了許多有用的方法(fe, strcat )來填補空白。 運行此腳本將產生以下輸出:
** Compiling the BTrace script ...
*** Compiled
** Instrumenting 1 classes ...
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 25ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 3ms
Method org.springframework.data.mongodb.core.MongoTemplate::getDb executed in 22ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 19ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 3ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::getDb executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 6ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 0ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::getDb executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::prepareCollection executed in 6ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 1ms
Method org.springframework.data.mongodb.core.MongoTemplate::access$100 executed in 0ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 2ms
Method org.springframework.data.mongodb.core.MongoTemplate::maybeEmitEvent executed in 1ms
...
如您所見,輸出包含一堆內部類,可以通過提供更精確的方法名稱模板(或者甚至可以跟蹤MongoDB驅動程序)來消除它們。
我才剛剛開始發現BTrace,但是使用該功能強大的工具對開發人員來說, 無疑是很有價值的。
參考: BTrace:我們的JCG合作伙伴 Andrey Redko在Andriy Redko {devmind}博客上的Java開發人員工具箱中的隱藏寶石 。
翻譯自: https://www.javacodegeeks.com/2012/08/btrace-hidden-gem-in-java-developer.html