初探BTrace指令碼 - 看看持續整合哪個環節比較慢
需求
這幾天發現持續整合環境的執行效率比較低,所以想到用BTrace來看看是什麼原因造成的,哪些環節比較慢。
持續整合環境的服務端是hudson,裡面跑的主要是各個應用的單元測試,由maven管理執行。
獲取資源
從BTrace官方下載它的工具包 http://kenai.com/projects/btrace/downloads/directory/releases
我這邊下載的是 release-1.2 目錄下的1.2版本。
簡單的使用說明,可以參考使用者手冊:http://kenai.com/projects/btrace/pages/UserGuide
hudson中執行的是
hudson中跑的是單元測試程式碼內容類似如下:
package com.hugehard......test;
......
public class SomeBizServiceTest extends JTester {
......
@Test
public void testXX() {
...
}
@Test
public void testOO() {
...
}
...
}
所以我們需要監控的是單元測試類,這些類處於名稱包含hugehard的包路徑中。
我們希望知道testXX, testOO這樣的方法的執行時間。
編寫監控指令碼
package hudson;
import static com.sun.btrace.BTraceUtils.print;
import static com.sun.btrace.BTraceUtils.println;
import com.sun.btrace.BTraceUtils.Time;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.TLS;
/**
* BtraceHudson.java
*
* @author caesar 2011-7-30 AM11:23:17
*/
@BTrace
public class BtraceHudson {
@TLS
static long starttime = 0;
@OnMethod(clazz = "/.*hugehard.*/", method = "/test.*/")
public static void startMethod(@ProbeClassName String probeClass,
@ProbeMethodName String probeMethodName) {
print("probeClass: ");
print(probeClass);
print(" ");
print("probeMethodName: ");
print(probeMethodName);
print(" start time: ");
starttime = Time.nanos();
println(starttime);
}
@OnMethod(clazz = "/.*hugehard.*/", method = "/test.*/",
location = @Location(Kind.RETURN))
public static void collectTestMethodExecutionEnd(@ProbeClassName String probeClass,
@ProbeMethodName String probeMethodName) {
print("probeClass: ");
print(probeClass);
print(" ");
print("probeMethodName: ");
print(probeMethodName);
print(" execute time: ");
long executeTime = Time.nanos() - starttime;
println(executeTime);
}
}
上面這段程式碼是參考博文 http://jarit.iteye.com/blog/1010908 中的內容,所以這裡就不贅述它的原理了。
maven不能btrace?
我在自己的工程根目錄下,執行“mvn clean test”。
通過“jps -l”拿到maven的PID。
而後通過“btrace <PID> BtraceHudson.java”,期望能夠獲得每個測試方法的執行時間。
但是沒有獲得任何的資訊。
後來把標註 @OnMethod 中的clazz和method限定都放到最寬泛的程度,才發現,裡面拿到的方法執行資訊,根本與單元測試類毫無關聯,而都是來自maven的程式碼類。
這時候想起來,maven在執行每個工程的單元測試的時候,它會建立獨立的執行緒去執行它們pom.xml中定義的內容。
所以我這裡拿到PID,僅僅是maven自身的執行緒資訊,根本拿不到具體工程的執行緒中的方法執行資訊。
javaagent模式
根目錄的pom.xml中我們定義了jmockit的javaagent,用於執行test階段的單元測試mock程式碼之用。配置如下:
<project> <dependencies> ...... </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.2</version> <configuration> <argLine>-javaagent:"${settings.localRepository}/com/hugehard/external/test.jmockit/0.997/test.jmockit-0.997.jar"</argLine> <junitArtifactName>com.alibaba.external:test.junit</junitArtifactName> <testNGArtifactName>com.alibaba.external:test.testng.jdk15</testNGArtifactName> </configuration> <executions> <execution> <goals> <goal>test</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
這讓我想起來,btrace也是有agent模式的,可以讓它和應用一起啟動。
這樣每次maven建立新執行緒來執行單元測試的時候,會否也讓btrace一起啟動了呢?
參考官方文件,修改argLine配置如下:
<argLine>-javaagent:"${settings.localRepository}/com/hugehard/external/test.jmockit/0.997/test.jmockit-0.997.jar" -javaagent:/tmp/hudson-optimize/credit-shared-1/btrace-agent.jar=script=/tmp/hudson-optimize/BtraceHudson.class,scriptOutputFile=/tmp/hudson-optimize/btrace.${pom.artifactId}</argLine>
這裡需要說明一下:
1、javaagent模式下,需要預編譯btrace類
(詳細請參考 http://kenai.com/projects/btrace/pages/UserGuide#precompile)
所以我們需要用如下指令先編譯我們們的BtraceHudson.java
/work/ide/btrace/btrace-bin/bin/btracec -cp . BtraceHudson.java
而後會得到編譯好的類 BtraceHudson.class。
2、javaagent中,請確保給出的btrace-agent.jar所在的目錄中也包括了btrace-boot.jar, btrace-client.jar這兩個包。
3、我們可以在scriptOutputFile中指定btrace的輸出結果重定向到我們希望拿到報告的位置。
4、另外,這裡使用的${pom.artifactId} 是為了每個pom.xml對應的工程在執行單元測試的時候,它們所生成的btrace報告不會互相覆蓋。
接著像我們往常一樣,執行“mvn clean test”指令,就能在我們們指定的目錄中檢視btrace報告,而後對它進行分析,找出執行效率低下的單元測試了。
== 全文完 ==
相關文章
- 持續整合JenkinsBlueOcean初探Jenkins
- 一個比較好的shell指令碼指令碼
- 持續整合、持續部署、持續交付、持續釋出
- 持續整合持續部署持續交付_持續整合與持續部署之間的真正區別
- jenkins + Git 搭建持續整合環境JenkinsGit
- [譯] 自動化持續整合/持續分發,以節省更多時間編寫程式碼
- 持續整合、持續交付、持續部署簡介
- 關於持續整合打包平臺的Jenkins配置和構建指令碼實現細節Jenkins指令碼
- 整合持續整合工具
- Jenkins+iOS持續整合細節記錄JenkinsiOS
- ick:一個持續整合系統
- Go和Python比較的話,哪個比較好?GoPython
- iOS 持續整合iOS
- 淺談持續整合(CI)、持續交付(CD)、持續部署(CD)
- Jenkins實現持續整合 使用Ant指令碼構建ios專案Jenkins指令碼iOS
- 前端er,Jenkins持續化整合環境搭建前端Jenkins
- 在Ubuntu上安裝Drone持續整合環境Ubuntu
- 基於Jenkins快速搭建持續整合環境Jenkins
- 對持續整合、 持續交付、持續部署和持續釋出的介紹
- 一個Web 持續整合工作實踐Web
- 一個比較完整的Inno Setup 安裝指令碼指令碼
- Jenkins持續整合Jenkins
- 持續整合(CI)、自動化構建和自動化測試--初探 .
- Pythondifflib字串比較指令碼Python字串指令碼
- 從持續整合到持續交付——DockerCloud概覽DockerCloud
- 容器環境持續整合優化,Drone CI 提速 500%優化
- 基於 Docker 打造前端持續整合開發環境Docker前端開發環境
- 學哪種程式設計比較好,看看這六種語言!程式設計
- 談談持續整合,持續交付,持續部署之間的區別
- shell指令碼——比較兩個檔案大小、許可權指令碼
- 太多指令碼將會毀掉持續交付指令碼
- 通過Docker容器執行持續整合/持續部署Docker
- 《轉載》Jenkins持續整合-自動化部署指令碼的實現《python》Jenkins指令碼Python
- 持續整合配置之Nuget
- Taro 小程式持續整合
- Jenkins持續整合配置Jenkins
- 利用Jenkins+Gitlab搭建持續整合(CI)環境JenkinsGitlab
- Jenkins+Maven+SVN快速搭建持續整合環境(轉)JenkinsMaven