最近做压测的时候发现大报文总是tps很低,但是服务端用arthas测试正常,想着应该是jmeter的问题,这个又需要翻看源码,顺便记录下
下载和运行
在github仓库下载jmeter的源码,公司用的是jmeter3.1.x,就下载该版本的。
导入过程参考这篇博文,老版本,使用到ant,就下了个ant,ant确实效率低下,相较于maven存放依赖,ant管理项目的话还要下载jar包,idea右侧ant的download_jars来下载jar包,感觉下载超级慢,从maven中央仓库下载的… 下载完了之后,就可以install了,不再报错。
怎么修改ant的设置从其他仓库下载jar包
ant毕竟太老了,看了下build.xml里,有个maven.home的地方,不过没细瞅,就下载完了,以后碰到再看。
运行报错
- 内容:
WARNING: Could not open/create prefs root node Software\JavaSoft\Prefs at root 0x80000002. Windows RegCreateKeyEx(…) returned error code 5. - 原因:
注册表的问题,不影响运行,参考这篇博文
源码跟踪
压测大报文,性能相关的地方是载入jmx文件的过程,和最终传输到服务端这两个地方。参考这篇博文
相应的类和方法搜索,加对照源码,锁定为
- org.apache.jmeter.gui.action.Load loadProjectFile 读取文件
- org.apache.jmeter.save.SaveService loadTree 读取hashtree
- org.apache.jmeter.NewDriver main 入口
- org.apache.jmeter.JMeter runNonGui
- org.apache.jmeter.engine.StandardJMeterEngine runTest
- org.apache.jmeter.engine.JMeterEngine configure
具体流程梳理:
先进入org/apache/jmeter/NewDriver.java,反射调用JMeter的start方法
JMeter的start方法调用startNonGui方法
该方法调用runNonGui方法
private void startNonGui(String testFile, String logFile, CLOption remoteStart, boolean generateReportDashboard)
throws IllegalUserActionException, ConfigurationException {
// add a system property so samplers can check to see if JMeter
// is running in NonGui mode
System.setProperty(JMETER_NON_GUI, "true");// $NON-NLS-1$
JMeter driver = new JMeter();// TODO - why does it create a new instance?
driver.remoteProps = this.remoteProps;
driver.remoteStop = this.remoteStop;
driver.parent = this;
PluginManager.install(this, false);
String remoteHostsString = null;
if (remoteStart != null) {
remoteHostsString = remoteStart.getArgument();
if (remoteHostsString == null) {
remoteHostsString = JMeterUtils.getPropDefault(
"remote_hosts", //$NON-NLS-1$
"127.0.0.1");//$NON-NLS-1$
}
}
if (testFile == null) {
throw new IllegalUserActionException("Non-GUI runs require a test plan");
}
driver.runNonGui(testFile, logFile, remoteStart != null, remoteHostsString, generateReportDashboard);
}
runNonGui方法为真正核心代码,包括加载jmx和engine的操作
HashTree tree = SaveService.loadTree(f);
...
if (!remoteStart) {
JMeterEngine engine = new StandardJMeterEngine();
engine.configure(tree);
long now=System.currentTimeMillis();
println("Starting the test @ "+new Date(now)+" ("+now+")");
engine.runTest();
engines.add(engine);
}
engine为JMeterEngine接口,实现类为StandardJMeterEngine
问题诊断
用阿里巴巴的arthas进行诊断,步骤:
- 将arthas直接安装到jmeter的bin目录下,方便诊断
- 解压后先用jmeter开始压测
- 根据jmeter默认端口4445查看pid,命令
lsof -i:4445
- 启动arthas,命令
/app/aimUpload/jdk1.8/bin/java -jar arthas-boot.jar pid号
- 正常显示图标后,针对要诊断的类和方法用trace或tt测试,如
trace org.apache.jmeter.gui.action.Load loadProjectFile -n 3
- 检查耗时是否正常,了解耗时点在哪个方法上。
- 真正耗时点是业务代码…
com.asiainfo.utils.srvcaller.CenterClient call
现状
collector有问题,