JMeter远程分布式联机性能测试
by:授客 QQ:1033553122
测试环境
apache-jmeter-2.13
Java JDK版本:1.8
1、 JMeter分布式测试简介
当一个JMeter客户端因网络限制等因素,无法模拟足够的用户对服务器施压时,需要用到JMeter分布式测试:用一台控制机,控制多台远程负载机,同时对服务器施压。
2、 配置与实操
步骤1 选定客户端
选择一台本地机器,当作JMeter客户端(控制器),用于控制远程JMeter实例(也叫JMeter 引擎),即远程负载生成机,并收集来自从这些远程负载机的数据。
在本机上创建并调试脚本,保证脚本可运行。
步骤2 修改jmeter.properties配置文件
修改$jmeter_home\bin\jmeter.properties文件(形如D:\Program Files (x86)\Jmeter\apache-jmeter-2.13\bin\jmeter.properties),打开该文件,找到如下内容,并添加带背景色部分的内容:
# Remote Hosts - comma delimited
remote_hosts=127.0.0.1
remote_hosts=192.168.9.133:1099,192.168.9.66:1099
#remote_hosts=localhost:1099,localhost:2010
说明:如上,192.168.9.133,192.168.9.66分别为远程负载机的ip地址,端口1099为JMeter用于访问远程负载生成机的端口rmi.port,“ip地址:端口”之间以逗号分隔,按这种方式可以增加多个负载机,具体上限未知。
关于端口更改的说明(参考官方文档):
1)更改访问远程负载机的端口(假设改成1234
JMeter客户端:
启动前,修改jmeter.properties,找到如下带背景色内容:
#server.rmi.port=1234
修改为如下:
server.rmi.port=1234
服务器端:
Windows
进入cmd控制台操作:
C:\JMETER> SET SERVER_PORT=1234
C:\JMETER> JMETER-SERVER [other options]
linux
$ SERVER_PORT=1664 jmeter-server [other options]
2)更改供负载机监听远程请求使用的rmi端口
如果有必要的话,启动前,修改jmeter.properties,找到如下带背景色内容:
#client.rmi.localport=0
修改为如下
client.rmi.localport=xxx
说明:
1、client.rmi.localport=0表示随机分配端口,否则使用指定端口
2、个人理解,这里的端口是客户端和负载机建立TCP套socket接字时,分配给客户端的端口
3)为JMeter引擎指定一个固定端口(假设为3000
如果有必要的话,启动前,修改jmeter.properties,找到如下带背景色内容:
#server.rmi.localport=4000
修改成如下:
server.rmi.localport=3000
说明:啥时候需要改这个端口我也不是很懂
说明:以上3点未经过本人实践验证,仅供参考,通常使用默认的即可
步骤3 启动负载机
windows:
双击$JMeter_home\bin\jmeter-server.bat(形如D:\Program Files (x86)\Jmeter\apache-jmeter-2.13\bin\-server.bat)
Linux:
运行$JMeter_home\bin\jmeter-server
eg:
步骤4:验证测试
重新在JMeter客户机上开启Jmeter,载入调试好的脚本
如下,运行 -> 远程启动|远程全部启动,可以选择单独启动某个负载机或者一次性启动全部负载机
说明:
1、这里的启动负载机后会立即执行负载测试,我们可以通过
a) 查看结果树等监听器查看请求是否成功,为方便查看是否执行成功(看执行的请求数), 建议开始正式测试前,先把线程组设置为单线程,仅运行一次,等确定没问题以后再改成目标设置
注意:关于线程组中“线程数”的正确理解
举例说明:假设“线程数”设置为1,总的有2台负载机(每台负载机只运行一个JMeter实例),1台客户机,那么启动全部负载机进行负载测试时,总的线程数为 负载机数 x 线程数 = 2,也就说,每台负载机都会启动线程组中指定的“线程数”来执行负载测试
b)结合菜单“选项->Log Viewer”查看运行日志
c) 查看远程负载机输出是否正常,如下
我们可以看到,负载机成功执行了好几次,正常开始(Starting),正常结束(Finished)
2、客户机性能不够好或者网络不够好的情况下,一次性启动全部负载机可能会有点“卡”
步骤5:执行负载测试
说明:提前停止/退出
如果想停止远程负载机的测试,可以选择 运行 -> 远程停止|远程全部停止
如果想远程负载机退出程序,可以选择 运行 -> 远程退出|远程全部退出
3、 注意事项及问题分析
注意事项:
a)客户机上一定要保存并打开一份测试计划脚本
b)不需要复制测试计划脚本到负载机上,客户机会自动把脚本分发到负载机上
c) 每台负载机,客户端上安装的java jdk版本(至少保持大版本一致),特别是jmeter版本及插件,要保持一致,防止出错和执行效率等问题
d) 如果客户机上测试计划脚本,使用了参数文件,那么需要在负载机上相同路径下,放置对应文件的同名文件拷贝。需要认真检查每个插件使用的数据文件
举例说明:
比如,我的查看结果树监听器,把数据保存到了某个文件:F:\查看结果树.csv文件,那么我们要负载机器上的F:\路径下,存一份名为“查看结果树.csv”的对应文件拷贝
e) 客户机和负载机最好分开,由于客户机需要发送信息给负载机并且会接收负载机回传回来的测试数据,所以客户机自身会有消耗,所以建议单独用一台机器作为客户机。
f) 避免防火墙阻止对应端口的访问,最好把防火墙都关闭了。
问题分析
实践中遇到一个问题,就是JMeter可以启动负载机,但是启动后没能执行成功,没看到发起的请求,通过Log Viewer也没看到错误信息,后面咋办?
找日志,负载机上打开$JMeter_home\bin\jmeter-server.log,查看是否有报错信息,结果发现如下:
2016/10/31 20:37:20 ERROR - jmeter.samplers.BatchSampleSender: sampleOccurred java.rmi.ConnectException: Connection refused to host: 169.254.82.102; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.invoke(Unknown Source)
……(略)
Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.trans
如上,很好奇这个ip是哪里的,打开客户机,cmd命令查看
如上,原因就不用说了吧,解决方法如下:
确保万无一失,把客户机上“本地连接”除外的网卡适配器都禁用,然后重新启动客户机上的JMeter软件(一定要重启),重新打开负载机上的jmeter-server.bat,然后重新执行步骤4,OK
参考连接:
http://jmeter.apache.org/usermanual/remote-test.html