[TOC]
Jmeter简介
Jmeter是Apache开源的一个使用纯Java编写的压力测试工具,它最初是为测试web应用程序而设计的,但后来扩展到了其他测试功能。例如,可用于测试静态和动态资源以及web动态应用程序的性能等。Jmeter可以用来模拟对服务器、服务器组、网络或对象上的重负载,以测试其强度或分析服务在不同负载类型下的总体性能。
如今Jmeter是一个主流的、功能完善且强大的压测工具,由于是使用Java编写的,所以具有跨平台特性,可以运行在Windows、Mac、Linux等操作系统上。并且支持丰富的协议,如:HTTP/HTTPS、FTP、JDBC、SOCKET、SOAP。。。等,此外还有许多第三方插件支持以及第三方集成
相关网址:
- 官网地址:https://jmeter.apache.org/
- 下载地址:https://jmeter.apache.org/download_jmeter.cgi
- 用户手册:https://jmeter.apache.org/usermanual/index.html
配置Jmeter的测试计划
通过以上给出的地址将Jmeter下载好后,进入到Jmeter的bin目录下,启动脚本放在这个目录,其中windows双击jmeter.bat即可,Mac和Linux下则是使用如下命令运行:
sudo sh {JMETER_HOME}/bin/jmeter.sh
初次运行可能会比较慢,启动成功后,界面如下:
接下来我们看看如何使用Jmeter对接口进行压测,我现在有一个商品列表接口,接口路径为:/goods/to_list
。
想要使用Jmeter对这个接口进行压测的话,首先右击左边栏的“Test Plan”(测试计划),添加一个“Thread Group”(线程组),如下图所示:
接着简单配置一下请求线程数之类的,线程数就代表着并发数:
因为该接口是通过HTTP请求的,所以需要添加一个HTTP请求默认值,如下图:
配置接口服务的请求协议、ip地址以及端口号,这样后面添加HTTP请求的时候就不需要重复填写这些信息了,可以起到一个通用配置的作用:
然后添加一个HTTP请求:
这里只需要配置接口路径以及请求方法即可,因为Jmeter会自动帮我们拼上之前配置的HTTP请求默认值:
为了查看测试结果,还需要添加一些监听器,监听器有很多种,也可以添加多个,这里我添加了一个聚合报告:
以及一个图形结果:
开始测试
在上一小节中,介绍了如何针对一个现有的接口配置测试计划,按照以上步骤配置完成后如下:
现在我们就可以开始执行这个测试计划了:
测试运行完成后,可以在聚合报告中看到压测的统计数据:
简单说明下这些统计指标:
- Samples:采样数/请求数
- Average:平均响应时间,单位毫秒
- Median:响应时间的一个中间值,单位毫秒
- 90%Line:90%的请求响应时间,单位毫秒
- 95%Line:95%的请求响应时间,单位毫秒
- 99%Line:99%的请求响应时间,单位毫秒
- Min:请求最小响应时间,单位毫秒
- Maximum:请求最大响应时间,单位毫秒
- Error %:响应错误率
- Throughput:每秒的吞吐量
- Received KB/sec:每秒接收的数据量
- Send KB/sec:每秒发送的数据量
如果此时查看图形结构的话,会发现只有一点点线条,这是因为我们将线程组的线程数设置太小了:
可以尝试将线程数设置到1000,然后清除之前的测试报告数据:
然后再运行这个测试计划,运行完成后再打开图形结果就可以看到曲线图了,如下:
命令行压测
以上小节介绍了Jmeter的基本使用,但都是基于可视化界面操作的。在某些情况下我们可能需要在服务器上进行测试,而绝大多数服务器系统都只有命令行。好在Jmeter支持命令行下的操作,所以本小节将介绍在命令行下如何使用Jmeter做压测。
首先第一步是在当前的操作系统下在可视化界面上配置好测试计划并将其存储为jmx文件,在这一步我们直接将之前所演示的测试计划另存为jmx文件即可。“file” -> “Save Test Plan as”:
- Tips:jmx文件内容格式为xml,实际上就是描述了测试计划的配置信息,感兴趣的话可以自行打开瞧一瞧
第二步是将这个jmx文件上传到服务器上,我这里的操作系统是Mac OS,所以使用scp
进行上传:
scp MyWorkSpace/TestFiles/goods_list.jmx root@${server_ip}:/home/goods_list.jmx
- Tips:如果是windows系统,可以使用
rz
命令,直接选择上传的文件即可。
上传完成后,使用Jmeter的shell脚本jmeter.sh
执行该jmx文件:
[root@server ~]# cd /usr/local/apache-jmeter-5.1.1/bin/
[root@server /usr/local/apache-jmeter-5.1.1/bin]# ./jmeter.sh -n -t /home/goods_list.jmx -l /home/result.jtl
参数说明:
- -n:非图形界面启动
- -t:指定需要执行的jmx文件路径
- -l:指定结果文件的存储路径
执行该测试计划后,想要知道压测是否正常进行的话,可以使用top
命令查看系统负载。我这里很明显是正常执行压测了,CPU负载达到了19.72
:
执行结束后会输出一些测试结果的统计信息:
正常情况下执行结束会生成一个测试结果文件,存放在我们使用参数-l
指定的路径下。如下:
最后把生成的result.jtl
文件下载到本地,并导入到Jmeter中。“Aggregate Report” -> “Browser” -> “Open”:
此时就可以看到测试结果的聚合报告了:
自定义变量模拟多用户
上面两小节我们简单介绍了Jmeter的基本使用,而本小节则将介绍一个在Jmeter中很实用的功能:自定义变量。有过一些测试经验的小伙伴应该知道在很多接口的测试用例下,我们可能需要模拟多个用户对某一接口进行请求,这时候通过使用Jmeter里的自定义变量就能实现这个功能。当然自定义变量不仅仅是用来模拟多用户,这里只是举一个实际的应用例子。
在一个线程组里可以添加多个HTTP请求,如果希望一次只测试一个接口的话,可以将其他测试请求给禁用掉。例如这里将之前所添加的“商品列表”给禁用,右击“商品列表”选择“Disable”:
现在我有一个可以通过token获取用户信息的接口:/user/info
,该接口需要接收一个参数,即用户的登录token。根据该接口添加一个新的HTTP请求,具体配置如下:
按照如此配置,每次请求传递的都是同一个token,这样就只能针对一个用户进行测试。若要模拟多用户,自然不能将token写死在这里,而是将其抽取成一个变量,这也就是所谓的自定义变量了。在Jmeter中自定义变量,首先需要添加一个“CSV Data Set Config”。如下图所示:
然后创建一个配置文件,配置文件的内容是有一定格式的,需要使用分隔符分隔,分隔符可以是任意的可识别符号,例如我这里使用逗号进行分隔:
$ cat config.txt
13000000001,149787a6b7986f31b3dcc0e4e857cd2a
13000000002,078563f337ec6d6fedf131ddc857db19
13000000003,7692dcdc19e41e66c6ae2de54a696b25
13000000004,0f3e84acb19dff22f695f31dbe3e972a
13000000005,268e27056a3e52cf3755d193cbeb0594
13000000006,00c66aaf5f2c3f49946f15c1ad2ea0d3
接着根据配置文件和实际需求编辑如下选项,让Jmeter可以从配置文件中读取配置项:
- Tips:这里定义的变量名中userId对应的是配置文件中的第一列,而token则是对应的第二列,以此类推。另外,分隔符必须与配置文件中的分隔符保持一致,这样Jmeter才能正常构建变量与配置的映射关系
在使用的时候,通过${变量名}
引用自定义变量即可,如下示例:
这样Jmeter就会从配置文件中读取不同的token并赋值给我们定义好的变量,那么每次请求就可以传递不同的token,以达到模拟多个用户请求的效果。
在上一小节中我们介绍过命令行下的压测方式,但如果我们配置的测试计划用到了自定义变量, 且定义了配置文件的路径。而服务器上的文件路径肯定和本地操作系统的文件路径不一样,那么要如何更改配置文件的路径呢?
首先将jmx文件和配置文件一并上传到服务器上,接着打开jmx文件并查找到CSVDataSet
标签,然后将描述配置文件路径的子标签的值改为服务器上配置文件所在的正确路径即可。如下图所示:
Redis压测工具 - redis-benchmark
Redis作为缓存中间件,其性能瓶颈会影响到系统的整体性能,所以通常我们也需要通过压测的方式确定Redis服务的性能瓶颈是多少。而Redis自带了压测工具:redis-benchmark
,本小节将简单介绍该工具的使用。
该工具的使用也比较简单,如果只是做一个压测的话,只需要使用如下命令即可:
[root@server ~]# redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000
参数说明:
- -h:指定host,即redis服务所在的ip地址
- -p:指定端口号
- -c:指定并发请求数量
- -n:指定发送多少个请求
执行该命令后,控制台会输出相应的压测结果。观察输出的信息会发现,该命令会逐个对redis的一些主要指令进行压测,我这里就截取了get
指令的压测结果。如下:
====== GET ======
# 10w个请求在1.58秒内执行完毕
100000 requests completed in 1.58 seconds
# 100个并发客户端
100 parallel clients
# 每个请求数据包大小为3字节
3 bytes payload
keep alive: 1
# 48.00%的请求耗时小于等于1毫秒
48.00% <= 1 milliseconds
# 99.66%的请求耗时小于等于2毫秒
99.66% <= 2 milliseconds
# 100%的请求耗时小于等于2毫秒
100.00% <= 2 milliseconds
# 每秒可完成63411.54个请求,即QPS
63411.54 requests per second
如果希望压测时指定每个请求的数据包大小可参考如下命令:
[root@server ~]# redis-benchmark -h 127.0.0.1 -p 6379 -q -d 100
参数说明:
- -q:表示quiet,即不输出详细信息,仅输出每个指令的QPS信息
- -d:指定每个请求的数据包大小,单位为字节
如果只想压测指定的命令,则可以使用-t
参数来指定,如下示例:
[root@server ~]# redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -q -n 100000
如果想压测某条具体的指令,那么则可以使用script load
来指定脚本。如下示例:
[root@server ~]# redis-benchmark -h 127.0.0.1 -p 6379 -q -n 100000 script load "redis.call('set', 'foo', 'bar')"