在某天,突然接到一个需求要对集群某个接口进行性能测试。线上单机器(4c8g)集群大概有十几台。线上平常的 TPS:1500。(不含突发高流量,最近业务的增加,这个也是为啥压测了)

于是乎,我们就开始吧啦吧啦开会讨论。最开始的问题是怎么模拟线上环境。基于没有性能环境,只能自己搞,考虑降本增效,模拟线上环境,成本很高。那么我们就只能找到梯度然后去毛估性能指标。可是怎么找到这个性能指标?线性增加?理想状态下,当乘积的系数翻倍,那么结果也是翻倍。可是这不是理想状态下😂 😂 😂 。所以这个梯度就只能我们去压测找出这个增加的趋势是怎么样的。

于是乎,我就去把测试环境的机器都搞成和线上一样的配置 4c8g 的,然后去压测,然后 1 台,2 台,3 台,5 台。看出增加的趋势。
本来测试使用电脑的配置,就很低了,别说 1500,可能最多支持 500 的并发,而且还不能持久。

所有搞了几台 2c4g 的机器,本来想着是每个机器单独跑,无非是切换几次窗口就好了😁 😁 。后来切,切,切.....。蒙圈了。然后就想起了分布压测。决定试试。
大概就是这样的(如下图)。比较懒,感觉这个图,还是很好的就截下图。

然后就开始动手了。把我电脑(mac 系统)当成主压力机,liunx(压力机)
linux 机器,先配置 JDK(这里就不说了。自行百度)
再配置 jmeter。主要就一个环境变量。
vi /etc/profile 输入:export PATH=/opt/apache-jmeter-5.3/bin/:$PATH

输入 jmeter -v 测试下,这样就 OK 了。

可以在上传文件运行下 jmx 文件
非 GUI,jmeter -n -t xxx.jmx 看到有正常的输出就 OK 了。命令很简单(网上有很多,可以看下)

然后配置下压力机和主压力机连接的配置
修改,jmeter.properties,文件中的 remote_hosts =ip(本机 ip) server.rmi.ssl.disable=true

把 jmeter 后台挂起,nohup jmeter-server &,查看下进程或者 ps axu | grep jmeter,有就可以了。

配置主压力机
修改,jmeter.properties,remote_hosts =ip(压力机 ip)server.rmi.ssl.disable=true。

配置完成之后
在主压力和压力机上,相互进行 ping 下,看看是否有问题。如果平不同,分布式就会出问题。

jmeter -n -t xxx.jmx -R 压力机 ip
这样就算是 OK 的

特别要注意两点。
1.关闭防火墙:firewall-cmd --state //查看防火墙状态。systemctl stop firewalld.service //关闭防火墙
2.关闭虚拟网卡
3.如果使用 csv 进行参数化,需要把参数文件/jar....等文件在每台压力机上拷贝一份,最好都放置在 bin 目录下,因为 Jmeter 会直接从 bin 目录下查找;

遇到的坑
坑一:

这个样的问题大概就是网络不同,存在多个网卡,导致的。
解决方案:看下主压力机和压力机之间的 ip 是不是存在多个。配置好对应 ip。

坑二:
java.net.SocketException,Non HTTP response message: Connection reset,
Non HTTP response code: org.apache.http.NoHttpResponseException,Non HTTP response
在 1000 个线程跑的时间,偶尔会出现这样的异常。百度下 原因:java.net.SocketException:(Connection reset 或者 Connect reset by peer:Socket write error)。该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的 Socket 被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常 (Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。
解决方案:扩容 jmeter 的初始化参数。修改 jmeter 的分配资源:bin/jmeter 文件的,xmx,xms,size 属性。

坑三:
单机器跑 1000 线程,tps 到 1500 左右。用分布式调用,发现,tps 只有 300 多。很奇怪。不同的网络,导致的网络延迟,主 - 压力机 - 被测试机器,分别在三个不同的网段中。
解决方案:把机器分布到同一个网段内。可以看下 ping 的响应时间。

毫秒的差别在高并发的情况下还是有很大的影响的。

坑四(也是自己学艺不精):
关于 tps 的换算。之前一直以为 100 的线程最高 tps=100。tps 时间单位是 s。要根据具体的接口响应时间的快慢进行换算。
比如,接口响应时间:10ms。100 线程 tps 最大是 1w。压测的过程中,tps 和响应时间,线程数有很多大关联。当响应时间到达某个节点时间 tps 会下降的。

所以压测 tps 时,不能硬件 cpu、内存.....等等为性能标准,有可能拿到的指标是不准的。

还有些没有遇到的坑:

问题:
在 slave 上(linux 系统)运行 jmeter-server 时,出现 “An error occurred: Cannot start. localhost is a loopback address” 错误

解决方案:
方法一:运行以下命令:./jmeter-server -Djava.rmi.server.hostname=(本机 ip)
方法二:修改 jmeter-server 文件 vi jmeter-server 将 jmeter-server 中的 RMI_HOST_DEF=-Djava.rmi.server.hostname=(本机 ip)

问题:
远程启动 slave 机器时,如出现 “Jmeter nested exception is:java.net.ConnectException connection timed out:connect ” 错误
解决方案:

1)查看 slave 上的 ip 与 master 配置文件中的 ip 是否一致;
2)查看防火墙是否关闭

问题:
当设置 csv 文件路径时,如果路径不对,无响应。
解决方法:将 csv 文件以 “相对路径” 命名,即将 csv 文件直接放入 bin 目录下,在 Jmeter 路径中直接写入文件名

问题:
(Linux)默认端看 1099 被占用,如何关闭某个被占用端口的方法

1)netstat -ntlp //查看当前所以 tcp 端口

nestat -ntulp |grep 1109 //查看所有 1109 端口使用情况

2)lsof -i:1109 //查看占用 1109 端口的程序 pid

3)kill -9 1109 //kill 掉该进程

问题:
如果使用 slave 发送数据后,长时间无响应

问题排查:
1)查看发送的数据中是否存在 csv 参数文件,查看 slave 机器的 bin 目录下是否有该文件;
2)查看建立的 tcp 采样器中属性 “TCPClientclassname” 处是否添加协议:org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl

问题:
如果你的 JMeter 返回数据是乱码

解决方法:在 JMeter 安装路径的 bin 目录下,打开文件 jmeter.properties,把 Sampleresult.default.encoding 的值改为 utf-8 即可。

问题:
启动 jmeter 时,报错:Error occurred during initialization of VM Could not reserve enough space for object heap errorlevel=1

解决方法:
1)bin 目录下打开 jmeter 文件,bin/jmeter 文件的,xmx,xms,size 属性。

问题:
当 jmeter 用作数据库 API 测试时,如果数据库接口中参数中传递一个数组,如 getApps(int nu, int appID[ ]),实际使用过程中报语法错误

解决方法:可尝试在调用该接口传参中加入关键字 “ARRAY”,如 getApps(3, ARRAY[7,8])

学无止境,有望有缘的朋友进行留言交流!!!!


↙↙↙阅读原文可查看相关链接,并与作者交流