Jmeter-分布式压测配置及常见问题(一文全)
Jmeter-分布式压测傻瓜式配置及常见问题的解决
参考Jmeter官网内容 http://jmeter.apache.org/usermanual/jmeter_distributed_testing_step_by_step.html
一、为什么要做分布式??
1、Jmeter 本身的局限性
- 一台压力机的 Jmeter 默认最大支持 1000 左右的并发用户数(线程数),再大的话,容易造成卡顿、无响应等情况,这是受限于
Jmeter 其本身的机制和硬件配置(内存、CPU等) - 由于 Jmeter 是 Java 应用,对 CPU 和内存的消耗较大,在需要模拟大量并发用户数时,单机很容易出现 JAVA
内存溢出的错误,导致测试脚本本身就有瓶颈
2、JVM 堆内存的局限性
ava 应用的 jvm 堆内存 heap 受压力机硬件限制,虽然我们可以调整堆内存大小
cmd 启用 Jmeter GUI 时,也会有提示
increase Java Heap to meet your test requirements: Modify current env variable HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" in the jmeter batch file
翻译:增加 Java 堆内存来满足测试的要求
但是单机无法支撑数以万计大并发,此时,需要多个压力机进行分布式压力测试,这样性能瓶颈就不会是我们的压力机了
3、联想场景
- 测试 5000 并发的场景,但单机只能支持 1000 并发无法达到 5000
- 通过分布式(5 台机器起)可以模拟 5000 并发
但是单机无法支撑数以万计大并发,此时,需要多个压力机进行分布式压力测试,这样性能瓶颈就不会是我们的压力机了
4、分布式压测
Jmeter 支持分布式压测,将需要模拟的大量并发用户数分发到多台压力机,使 Jmeter 拥有更大的负载量,满足真实业务场景(高并发场景)
5、分布式的最终目的
- 确保压力机不会出现性能瓶颈
- 在后面进行性能分析时,不需要考虑压力机是否会导致性能瓶颈的主要原因之一
二、Jmeter分布压测的原理
1、Jmeter分布式测试时,选择其中一台作为控制机(Controller),其它机器做为代理机(Agent)。
2、执行时,Controller会把脚本发送到每台Agent上,Agent 拿到脚本后开始执行,Agent执行时不需要启动Jmeter,只需要把jmeter-server.bat文件打开,它应该是通过命令行模式来执行的。
3、执行后,Agent会把结果回传给Controller,Controller会收集所有Agent的信息并汇总。
先杀个原理图:
这个图说明的是要一台控制机,然后由这台控制机发压测脚本到每台远程执行机,然后由控制机收集执行机结果
首先,在我们开始之前,有几件事要检查:
1.系统上的防火墙已关闭或打开了正确的端口。
2.所有客户端都在同一子网中。
3.如果使用192.xxx或10.xxx IP地址,则服务器位于同一子网中。如果服务器不使用192.xx或10.xx IP地址,则应该没有任何问题。
4.确保JMeter可以访问服务器。
5.确保在所有系统上使用相同版本的JMeter和Java。混合版本将无法正常工作。
6.您已经为RMI设置了SSL或将其禁用。
三、环境准备
Jmeter安装包和JAVA jdk 安装包自行下载:
Jmeter官网链接:https://jmeter.apache.org/download_jmeter.cgi
Java_jdk官网链接:https://www.oracle.com/technetwork/java/javase/downloads/index.html
客户端 | IP地址 | 主从 | 配置环境 |
---|---|---|---|
Mac | 用ifconfig查看/网络偏好设置-高级-TCP/IP | Master(控制机) | Jmeter 4.0,JAVA jdk |
Ubuntu 16.04 | 10.211.55.9 | Slave(执行机) | Jmeter 4.0,JAVA jdk |
CentOS 7 | 10.211.55.6 | Slave(执行机) | Jmeter 4.0,JAVA jdk |
(环境方面的配置就不做介绍了,不懂的话问度娘吧!)
这里简单介绍一下Jmeter的bin目录下的文件:
# bin:是核心可执行文件,目录下常用文件配置有:
jmeter.bat: windows启动文件:
jmeter: mac或者linux启动文件:
jmeter-server:mac或者Liunx分布式压测使用的启动文件
jmeter-server.bat:mac或者Liunx分布式压测使用的启动文件
jmeter.properties: 核心配置文件
examples:压测脚本文件JMX和动态读取csv参数文件案例
result—template:可视化HTML
template:JMX的模板文件
四、执行机slave配置
在本地slave机器的Jmeter的bin目录下,找到一个为jmeter.properties的文件,在文件内容中找到remote_hosts字段,添加一个远程负载机的IP地址,负载机查询本机IP并填入,端口默认是1099。
这里要特别注意端口后,有些资料说明端口1644为jmeter的controller 和agent 之间进行通信的默认RMI端口号,但是在测试时发现,设置为1644运行不成功,改成1099后运行通过。另外还要留意agent的机子是否开启了防火墙等。
配置完了启动jmeter-sever.bat
启动以后看到这个就基本👌了
五、调度机master配置
master机与slave机器的配置相似,同样在Jmeter的bin目录下,找到一个为jmeter.properties的文件,在文件内容中找到remote_hosts字段,添加本机的IP以及slave机IP。如果有多台代理机,这里需要把所有的代理机的IP地址和端口号都加入进来。
配置完了启动master机的jmeter-sever.bat服务,设置完成了
六、master运行分布式测试
1、添加线程组,编辑线程数,设置1个线程数,循环1次,这里只做示例
2、添加http请求,这里以访问www.baidu.com为例。
3、添加察看结果数和聚合报告,点击运行,可以选择远程启动或者远程全部启动,如果是点击远程启动,可以选择任意一台电脑来运行,如果是点击远程全部启动就会运行控制机和所有的代理机
出现这个说明数据接收成功
4、这里以点击远程全部启动为例。运行结束后,查看聚合报告,每台电脑设置的线程数为1,这里一共是两台电脑,所以是2个线程数。
5.jmeter分布式测试中master机的测试结果响应数据为空,原因是:
分布式测试中,通过远程启动代理服务器,注重的而是高并发,默认查看结果树中的响应数据为空,只有错误信息会被报回。
如果想要结果返回,直接把bin\jmeter.properties文件中的 mode=Standard 之前的 # 号去掉,重启jmeter即可
6.命令行启动远程分布式
jmeter -n -t xxx.jmx -r -l results.jtl -e -o /path
n:以非GUI形式运行Jmeter
t:表示要运行的jmx脚本路径
l:result.jtl 运行结果保存路径(.jtl),此文件必须不存在
r:指远程将所有agent启动
e:在脚本运行结束后生成html报告
o:用于存放html报告的目录
Jmeter进行分布式测试时需要特别注意的
1)如果使用csv进行参数化,需要把参数文件在每台slave上拷贝一份,最好都放置在bin目录下,因为Jmeter会直接从bin目录下查找;
2)slave机器执行脚本时,若断言执行成功则在master机器上是看不到请求响应数据的,只有在断言出错时才可键slave的返回;
3)若要使用Jmeter分布式进行测试,TCP取样器中“TCPClient classname”该栏必须填写对应的协议;
4)以十六进发送tcp数据包时,TCP取样器中“End of line(EOL) byte value”必须填写数据包的结束符,否则jmeter会一直等待,无响应。
七、Jmeter分布式测试常见问题
问题1:
在master上运行jmeter-server.bat时,出现“Exception creating connection to:192.16..;nested exception is:java.io.FileNotFoundException:rmi_keystore.jks(系统找不到指定的文件)”错误
解决方案:
修改apache-jmeter/bin/jmeter.properties 参数:server.rmi.ssl.disable=true
备注:将master和slave机器上的jmeter.properties文件 参数server.rmi.ssl.disable均改为true
其中linux上是用以下命令:vi jmeter.properties 使用/server.rmi.ssl.disable/进行查找
问题2:
在slave上(linux系统)运行jmeter-server时,出现“An error occurred: Cannot start. localhost is a loopback address”错误
解决方案:
方法一:运行以下命令:./jmeter-server -Djava.rmi.server.hostname=192.16..(本机ip)
方法二:修改jmeter-server文件
vi jmeter-server 将jmeter-server中的RMI_HOST_DEF=-Djava.rmi.server.hostname=192.16..(本机ip)
运行./jmeter-server即可
备注:Linux下后台执行,启用server:nohup ./jmeter-server -Djava.rmi.server.hostname=192.16.. &
查看确定jmeter是否启动成功:ps axu | grep jmeter
问题3:
远程启动slave机器时,如出现“Jmeter nested exception is:java.net.ConnectException connection timed out:connect ”错误
解决方案:
1)查看slave上的ip与master配置文件中的ip是否一致;
如果不一致,查看slave机器上是否有虚拟网卡,将网卡关闭,在此启动Jmeter-server.bat,查看是否正确
2)查看防火墙是否关闭
注:centos7上关闭防火墙: firewall-cmd --state //查看防火墙状态
systemctl stop firewalld.service //关闭防火墙
问题4:
当设置csv文件路径时,如果路径不对,无响应
解决方法:
将csv文件以“相对路径”命名,即将csv文件直接放入bin目录下,在Jmeter路径中直接写入文件名
问题5:
(Linux)默认端看1099被占用,如何关闭某个被占用端口的方法
1)netstat -ntlp //查看当前所以tcp端口
nestat -ntulp |grep 1109 //查看所有1109端口使用情况
2)lsof -i:1109 //查看占用1109端口的程序pid
3)kill -9 1109 //kill掉该进程
(windows)上关闭已被占用的端口
http://www.jb51.net/os/windows/203315.html
如1099端口被占用:1)在cmd命令行下输入以下命令:netstat -aon|findstr "1099",回车之后就可以看见列表中的PID,然后根据PID在电脑的任务管理器中查看对应的占用程序,然后将其关闭即可;2)然后根据查询的PID找到对应的进程,我们可以看到占有1099这个程序的进程ID,如:5264,继续输入命令【tasklist|findstr "5264"】,5264就是进程ID,现在知道是哪个进程占用的我们的端口,即可在任务管理器中杀掉该进程。
问题6:
如果使用slave发送数据后,长时间无响应
问题排查:
1)查看发送的数据中是否存在csv参数文件,查看slave机器的bin目录下是否有该文件;
2)查看建立的tcp采样器中属性“TCPClient classname”处是否添加协议:org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl
问题7:
如果你的JMeter返回数据是乱码
解决方法:
在JMeter安装路径的bin目录下,打开文件jmeter.properties,把Sampleresult.default.encoding的值改为 utf-8 即可。
问题8:
启动jmeter时,报错:Error occurred during initialization of VM Could not reserve enough space for object heap errorlevel=1
解决方法:
1)bin目录下打开jmeter.bat文件,查找set HEAP,将set HEAP=-Xms128m -Xmx512m修改为set HEAP=-Xms512m -Xmx512m;2)重新启动jmeter.bat即可
问题9:
当jmeter用作数据库API测试时,如果数据库接口中参数中传递一个数组,如getApps(int nu, int appID[ ]),实际使用过程中报语法错误
解决方法:
可尝试在调用该接口传参中加入关键字“ARRAY”,如getApps(3, ARRAY[7,8])
更新中....