背景:本次是为了支持多人同时运行,互不干扰的场景
为了满足这个场景需要解决一系列问题
1、什么机制支持多人同时运行?
为了获取答案,尝试了很多方式
第一个方式:2个独立jmeter客户端分别运行
场景:在同一个服务器上安装2个jmeter,当触发2个测试计划时分别执行2个不同的jmeter。
结论:当运行2个测试计划时,jtl报告虽然会生成2个独立的测试报告,但依旧以最后执行完的时间点同时生成2个测试报告,实际上依旧没有做到互补干扰。
第二个方式:1个master客户端,2个不同服务器上的远程server
场景:在不同的服务器上安装2个jmeter,分别启动jmeter-server服务,端口一致,默认1099端口,通过一个master控制2个server运行
首先,master的jmeter.properties修改如下:
remote_hosts=172.16.1.209:1099,172.16.3.250:1099
server_port=1099
server.rmi.port=1099
server.rmi.localport=1099
server.rmi.ssl.disable=true
远程服务的server的jmeter.properties配置如下:
server.rmi.ssl.disable=true
分别在server端开启服务:
./jmeter-server -D java.rmi.server.hostname=172.16.13.48
结论:远程的请求方式会生成2个独立的jtl文件,并按照各自的测试计划结束,可以互相独立,但需要将所有的参数化csv文件在所有服务器上同步,那么同一个服务上是否可以启动多个server来实现。
第三个方式:1个master客户端,2个相同的服务器上的远程server
场景:在同一个服务器上安装2个jmeter,分别启动jmeter-server服务,端口区分,通过1个master控制2个server
首先,master的jmeter.properties修改如下:
remote_hosts=172.16.1.209:1009,172.16.1.209:1029
server_port=1009
server.rmi.port=1009
server.rmi.localport=1009
server.rmi.ssl.disable=true
远程服务的server的jmeter.properties配置如下:
remote_hosts=172.16.1.209
server_port=1029
server.rmi.port=1029
server.rmi.localport=1029
server.rmi.ssl.disable=true
分别在server端开启服务:
在jmeter 1开启服务:./jmeter-server -D java.rmi.server.hostname=172.16.13.48 -Dserver_port=1009 &
在jmeter 2开启服务:./jmeter-server -D java.rmi.server.hostname=172.16.13.48 -Dserver_port=1029 &
结论:远程的请求方式会生成2个独立的jtl文件,并按照各自的测试计划结束,可以互相独立。以上方案可行。
踩过的坑:
server.rmi.ssl.disable=true 这个一定要设置,否则报错exception is:java.io.FileNotFoundException:rmi_keystore.jks(系统找不到指定的文件)”错误
2、如何通过代码在实现远程调用?
既然在已经知道用远程请求可以实现,那么代码要如何实现呢?
为了获取答案,尝试了很多方式
第一个方式:通过java调用cmd命令行方式,执行远程命令
结论:需要确保代码生成的jmx文件可以执行运行,很遗憾,这个成本过高,而且也不是首选。
第二个方式:ClientJMeterEngine 类
ClientJMeterEngine clientJMeterEngine= new DistributedRunner(“ip:port”);
clientJMeterEngine.configure(testPlanTree);
clientJMeterEngine.runTest();
结论:使用ClientJMeterEngine通过不同的ip和端口的确可以发起远程请求
第三个方式:DistributedRunner 类
ReportGenerator reportGenerator = new ReportGenerator(logFile, logger);
testPlanTree.add(testPlanTree.getArray()[0], new RemoteThreadsListenerTestElement());
List engines = new LinkedList<>();
ListenToTest testListener = new ListenToTest(
TestPlanLauncher.ListenToTest.RunMode.REMOTE, true, reportGenerator);
DistributedRunner distributedRunner = new DistributedRunner(remoteProps);
distributedRunner.setStdout(System.out); // NOSONAR
distributedRunner.setStdErr(System.err); // NOSONAR
testPlanTree.add(testPlanTree.getArray(), logger);
distributedRunner.init(hosts, testPlanTree);
engines.addAll(distributedRunner.getEngines());
testListener.setStartedRemoteEngines(engines);
distributedRunner.start(hosts);
startUdpDdaemon(hosts, engines);
结论:使用DistributedRunner通过不同的ip和端口的确可以发起远程请求,那么DistributedRunner和ClientJMeterEngine有什么区别呢?
通过查看jmeter源代码,发现DistributedRunner调用的ClientJMeterEngine,所以底层还是ClientJMeterEngine,所以我们还是选用Distr