http://blog.csdn.net/gzh0222/article/details/9731031
Btrace是一個實時監控工具,可以無需修改應用代碼(事實上它修改了字節碼),來達到不可告人的秘密!這是性能調優和診斷的利器!
它可以獲取應用程序代碼的執行時間,他可以讓你無需修改代碼,幫你做時間的打點。它還可以做的有很多多!
但是,你需要編寫btrace腳本,它是一個java文件。在Eclipse中編寫java類很簡單,在linux上,vm不熟悉的可能就會比較痛苦了,並且腳本可復制性很強。
因此,我對btrace做了一個封裝和拓展,你無須再編寫java腳本,只需要敲幾個命令,便可以實現你想要的功能!
為了減少重復工作的增加,拓展工具提供了以下特色功能:
1) 命令行交互式方式
2) 封裝了常見的方法監控命令,無需再編寫btrace腳本
3) 集成了一些典型的監控對象,如druid連接池,sql監控,isearch等
4) 未改變原有的btrace功能,仍然支持btrace腳本方式
軟件獲取和運行
github:https://github.com/xxzmxx/btrace_extend/
svn co 到linux/windows某個位置,進入bin目錄
Linux: chmod +x btrace (賦予btrace 可執行權限)
windows無需操作。
命令行下,執行命令
./btrace [pid]
|
【pid可以通過jps獲取】
進入交互界面
提供命令行交互
原有的btrace是通過形如 btrace pid xx.java文件。通過本次改造,我們提供了命令行交互方式,增加用戶體驗:
輸入help,獲取可用的命令
btrace>help
-------------------------------------------------------------------------------------------------------------------------------
| CommandName CommandArgs CommandUsage
| time {clazzname methodname}[interval] collect response time ,and it can be executed by a interval set(s),;Example
| time java.lang.Thread start
2
|
| aggre {clazzname methodname}[interval] aggregation response time,it's a well fuction;Example
| aggre java.lang.Thread start
2
|
| call {clazzname methodname}[interval] when method called,it prints;Example
| call java.lang.Thread start
2
|
| jstack {clazzname methodname} when method called,it prints stackTrace;Example:
| jstack java.lang.Thread start
2
|
| file {filePath} based on old btrace funtion,it can be run from a java file.Example:
| file Test.java
|
| druid Monitor druid dataSource?Example
| druid
|
| isearch Monitor Isearch execute time ;Example
| isearch
|
| sql Monitor sql execute time ;Example
| sql
|
| sqlde Monitor sql execute time and print Sql ;Example
| sqlde
|
| quit exit btrace
| quit
| -------------------------------------------------------------------------------------------------------------------------------
|
btrace運行操作
btrace在運行監控時,控制台是阻塞輸入的。只有通過Ctrl+c,來向應用發送信號,btrace會有3個選項供選擇:
btrace>time java.lang.Thread start
StartMonitor [java.lang.Thread.start()] time(ms)
Please enter your option:
1
. exit
2
. send an event
3
. send a named event
|
1代表退出監控,回到btrace交互模式;
2代表發送一個事件,會觸發btrace去打印監控信息到控制台。如aggre 、file、druid、isearch、sql、sqlde命令均可以通過該方式,打印出監控信息
3發送一個指定名稱的事件,暫時未支持
命令演示
本次拓展,共支持9個命令功能。
1)time
usage:time clazzname method [interval]
time功能為獲取指定類的方法的響應時間。並且它包含一個可選參數,即可以提供。
例子:我們想監控類com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp 中方法storeProductToDraftOrNormal的耗時情況。則輸入命令
btrace>time com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] time(ms)
|
btrace就開始收集這個方法調用的時間,如果這個方法被調用,就會打印出時間信息。
btrace>time com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] time(ms)
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
19
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
8
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
[Clazz.method] Time(ms)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
8
|
但是如果我的時間調用次數很多,就會出現殘酷的刷屏現象,我希望每隔2s進行采樣。輸入如下命令:
btrace>time com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
2
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] time(ms)
[Clazz.method] AvgTime(ms) Count(total)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
6
3
[Clazz.method] AvgTime(ms) Count(total)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
13
[Clazz.method] AvgTime(ms) Count(total)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
20
[Clazz.method] AvgTime(ms) Count(total)
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal
7
20
|
btrace會每隔2s收集一次信息,並對每次的信息做統計,包括均值和調用次數總計。
2)aggre
usage:time clazzname method [interval]
如果我們覺得time命令還是不夠滿足我需求,我希望能夠提供一些更詳細的值,比如在采集的這段時間,rt的最大值,最小值,均值,以及分布,還有調用總數。此時可以通過聚合命令來完成
例子:我們想監控類com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp 中方法storeProductToDraftOrNormal的耗時,並提供聚合報告。則輸入命令
btrace>aggre com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] By Aggregation time(ms)
|
通過觸發Ctrl+c,選擇選項2,獲取輸出結果:
btrace>aggre com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] By Aggregation time(ms)
Please enter your option:
1
. exit
2
. send an event
3
. send a named event
2
QUANTIZE
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp
value ------------- Distribution ------------- count
2
|
0
4
|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
45
8
|@@@
4
16
|
1
32
|
0
AVERAGE
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp
7
MAXIMUM
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp
19
SUM
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp
361
COUNT
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp
50
|
這里提供了針對時間的聚合信息,以ms為單位。並提供了時間分布的功能,可以清晰的看出該模塊時間是否穩定。
3)call
這個命令和time命令用法基本相同,請參考time命令
4)jstack
usage:jstack clazzname method
當應用中存在調用clazzname的method時,會打印出調用堆棧,這個方便我們查找問題。
例如想監控com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp 中方法storeProductToDraftOrNormal是否被調用,如果調用,希望看到它的堆棧。
btrace>jstack com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp storeProductToDraftOrNormal
StartMonitor [com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal()] && Print java stack info!
-------------------------------stack info--------------------------
com.alibaba.intl.ae.module.wsproduct.utils.WholesaleProductHelp.storeProductToDraftOrNormal(WholesaleProductHelp.java)
com.alibaba.intl.ae.module.wsproduct.persistent.AeProductForMysqlPersistent.persistent(AeProductForMysqlPersistent.java:
32
)
com.alibaba.intl.ae.morina.core.actionhandler.BasePublishActionHandler.invoke(BasePublishActionHandler.java:
69
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
67
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AeProductDetailInterceptor.intercept(AeProductDetailInterceptor.java:
40
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AeProductCatPropertyInterceptor.intercept(AeProductCatPropertyInterceptor.java:
101
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AeProductPostCountCheckInterceptor.intercept(AeProductPostCountCheckInterceptor.java:
51
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AeProductPersonAuthInterceptor.intercept(AeProductPersonAuthInterceptor.java:
45
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AeProductPunishInterceptor.intercept(AeProductPunishInterceptor.java:
32
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.AutoValidateProductInterceptor.intercept(AutoValidateProductInterceptor.java:
36
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.module.wsproduct.interceptor.MemberInfoInitializationInterceptor.intercept(MemberInfoInitializationInterceptor.java:
73
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.ActionHandlerInterceptorChainInvocation.invoke(ActionHandlerInterceptorChainInvocation.java:
63
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.AeProductPublishController.invoke(AeProductPublishController.java:
50
)
com.alibaba.intl.ae.morina.core.skeleton.publish.impl.AeProductPublishController.invoke(AeProductPublishController.java:
25
)
com.alibaba.intl.ae.morina.core.portal.InvocationControllerAutowirePostProcessor$
1
.intercept(InvocationControllerAutowirePostProcessor.java:
44
)
com.alibaba.intl.ae.morina.core.portal.InvocationControllerPortal$$EnhancerByCGLIB$$276335c.invoke(<generated>)
com.alibaba.intl.ae.module.wsproduct.service.AeProductPublishRemoteServiceImpl.postAeProduct(AeProductPublishRemoteServiceImpl.java:
36
)
sun.reflect.GeneratedMethodAccessor380.invoke(Unknown Source)
|
5)file
這個命令其實是為了保留btrace原始的監控方式。所以如果你編寫了btrace 腳本,那么直接使用:
file script.java
6)druid
該命令沒有參數,直接輸入druid即可。druid是一個數據庫連接池。在性能測試時,時常要監控連接池的飽滿情況,以及是否存在性能瓶頸,那么監控連接池的活動情況是很直接的方法。
例子如下:
btrace>druid
StartMonitor druid Connection DataSource
Please enter your option:
1
. exit
2
. send an event
3
. send a named event
2
------------------------------JDBC-URL------------------------------- avalibleConn activeConn totalConn Allconn useage%
dbc:mysql:
//10.20.147.144:3306/ws_product_press 4 0 4 20 20.0
dbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=
10.20
.
149
.
8
2
10
20
50.0
dbc:mysql:
//10.20.147.144:3306/ws_sku_press 6 0 6 50 12.0
dbc:alibaba:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=
10
7
2
9
10
90.0
|
7)sql
該命令沒有參數,直接輸入sql即可。如果你的應用包含數據庫操作,且使用ibatis框架,那么它會列出所有sql的操作時間,但是不顯示詳細sql,只顯示ibatis-id。如果要顯示詳細sql,使用sqlde命令獲取
btrace>sql
StartMonitor Ibtis Sql
Please enter your option:
1
. exit
2
. send an event
3
. send a named event
2
---------------------------------------------
Count
FREIGHT_TEMPLATE.selectByPrimaryKey
1290
WS_PRODUCT_DETAIL_DRAFT.selectByPrimaryKey
1290
WS_PRODUCT_DETAIL_DRAFT.deleteByPrimaryKey
1290
Min
FREIGHT_TEMPLATE.selectByPrimaryKey
0
WS_PRODUCT_DETAIL_DRAFT.selectByPrimaryKey
0
WS_PRODUCT_DETAIL_DRAFT.deleteByPrimaryKey
0
Max
WS_PRODUCT_DETAIL_DRAFT.selectByPrimaryKey
14
WS_PRODUCT_DETAIL_DRAFT.deleteByPrimaryKey
14
FREIGHT_TEMPLATE.selectByPrimaryKey
15
Average
FREIGHT_TEMPLATE.selectByPrimaryKey
0
WS_PRODUCT_DETAIL_DRAFT.selectByPrimaryKey
0
WS_PRODUCT_DETAIL_DRAFT.deleteByPrimaryKey
0
Sum
FREIGHT_TEMPLATE.selectByPrimaryKey
144
WS_PRODUCT_DETAIL_DRAFT.deleteByPrimaryKey
161
WS_PRODUCT_DETAIL_DRAFT.selectByPrimaryKey
186
Histogram
WS_CATE_CONSULT_CFGT.selectOldCategoryAttriNumber
value ------------- Distribution ------------- count
-
1
|
0
0
|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
469
1
|@@@@@@@
127
2
|@
28
4
|
12
8
|
7
16
|
2
32
|
0
WHOLESALE_STORE.findWholesaleStoreDOByCompanyId
value ------------- Distribution ------------- count
-
1
|
0
0
|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
587
1
|@@
37
2
|
8
4
|
6
8
|
6
16
|
1
32
|
0
Global Count
19150
|
ps.上述內容過於繁多,只選擇了部分。
8)sqlde
該命令沒有參數,直接輸入sqlde即可。該命令不但會聚合所有sql的rt,也會打印sql詳情。不過這個sql的排版目前做的還不是很好。會有些亂。建議還是使用sql命令來看。sql少的話,使用sqlde命令。