做为一名后端开发人员,熟练掌握一款性能测试工具很是有必要,这样有利于在技术选型时作一些参考。
常见的性能测试工具备:ab,JMeter,LoadRunner,他们都有各自的特色和应用场景:html
http://jmeter.apache.org/download_jmeter.cgijava
JMeter是基于Java开发的跨平台性能测试工具,官方提供了2种压缩格式的二进制包(zip和tgz),根据实际状况下载对应文件便可。
安装也很是简单,直接将压缩包解压到指定目录便可,以下示例:linux
$ tar xzvf apache-jmeter-5.2.1.tgz -C ~/opt
添加JMeter到环境变量PATH中,以下示例:git
$ export JMETER_HOME=~/opt/apache-jmeter-5.2.1 $ export PATH=$PATH:$JMETER_HOME/bin
配置好JMeter环境变量以后,在命令行终端中执行命令jmeter
便可启动JMeter图形化界面。web
使用JMeter分为3个步骤:shell
所谓测试计划就是一系列测试配置信息的集合,在JMeter中能够将这些配置信息保存为一个脚本文件(后缀名为“.jmx”)。
测试计划中涉及许多配置对象,详见:Elements of a Test Plan,理解这些配置对象是编写JMeter测试计划的前提,各个配置对象的名称及含义解释以下:apache
通常来说,上述对象之间具有嵌套关系,描述以下:
(1)一个测试脚本中只有一个Test Plan对象,而且做为其余对象的根。
(2)在Test Plan下能够有一个或者多个Thread Group(一般只须要有一个便可),能够有一个或者多个Listener,如:View Results Tree(以树型结构展现),还能够配置Assertion,Timer,Configuration Element,Pre Processor,Post Processor,Test Fragment,Non-Test Element。
(3)在Thread Group下能够配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Test Fragment,Listener。
(4)Controller下能够配置Controller,Sampler,Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。
(5)在Sampler下能够配置Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener。后端
用一个树型结构来描述各对象之间的嵌套关系以下:bash
如上所述,只有Test Plan,Thread Group,Controller和Sampler能够嵌套其余对象,而Assertion,Timer,Configuration Element,Pre-Processor,Post-Processor,Listener,Test Fragment和Non-Test Element不能再嵌套子对象。
实际上,在JMeter图形化界面中编辑测试计划时,指定对象下是否能够再嵌套子对象在操做菜单中就作了限制。服务器
以下图所示是一个在实际应用中可能会涉及到的对象嵌套关系配置示例:
而且对象在运行时的执行顺序以下:
首先,定时器(Timers),断言(Assertions),前置和后置处理器(Pre,Post-Processors)只有在应用它们的采样器存在时才会运行;
其次,控制器(Controllers)和采样器(Samplers)按照它们在测试计划配置树中出现的顺序执行;
最后,其余对象按照它们出现的范围和类型顺序执行,在一个特定类型的对象范围内,按照它们在测试计划配置树中出现的顺序执行;
上述这一堆阐述重点在于理解各个测试对象的做用,以及在什么位置使用它们,至于对象的执行顺序理解便可,不用死记硬背。
关于JMeter中的组件列表,详见:Introduction 。
JMeter的测试计划有2种方式生成:
最佳实践是针对不一样的场景选择对应的测试计划生成方式,好比:对于接口测试使用手动编写可能更加合适,而对于网页的测试,使用录制脚本的方式会更加方便。
在GUI模式下编辑测试计划时,关键在于理解清楚JMeter中涉及的配置对象的做用,在此基础上就能够借助图形化界面设计测试计划并将其保存为一个脚本文件。
具体的测试计划编写能够参考官方的一个Web测试计划示例:Building a Web Test Plan。
设置“Ramp-up period”参数
在手动编写测试计划时,值得注意点的是:线程池参数“Ramp-up period”值必定要设置合理,该参数的设置关系到测试启动时是否会给服务器带来很是大的冲击甚至过载,或者是达不到性能测试的要求。
“Ramp-up period”参数的含义是设置一个时长(单位:秒),使得在Thread Group中设置的线程根据该时长逐步启动。
举例说明:
(1)在Thread Group中设置线程数为10,Ramp-up period参数设置为100s,JMeter将会在100s内逐步启动10个线程,也就是说,每一个线程的启动间隔为10s(100s/10),可能最后一个线程启动的时候第一个线程已经结束。
(2)在Thread Group中设置线程数为100,Ramp-up period参数设置为10s,每一个线程的启动间隔为0.1s(10s/100),可能在测试刚启动时给服务器产生很大的负载。
综上所述,Ramp-up period参数值不能设置太大,也不能设置过小,JMeter官方文档的解释是:能够将该参数值与线程数设置为相同,或者比线程数略大或稍小便可。
根据经验来说,通常须要将Ramp-up period参数值设置比线程数略小更加合适。
其余一些关于Ramp-up period参数的设置技巧能够参考:
除了常见的Web测试,JMeter官方也给出了许多其余类型的测试计划示例,详见:User's Manual 。
录制测试脚本就是经过工具自动生成测试测试的方式,在JMeter中这种方式更适合于Web页面测试,可是实践中发现,自动生成的测试用例也很难直接就能用于性能测试,还须要对测试用例作一些调整。
不管怎样,有胜于无,经过脚本录制方式仍是能在必定程度上减小手动编辑测试计划的工做量。
在JMeter中录制测试脚本有2种方式:
更多关于录制JMeter测试脚本的实现能够参考以下博客:
1.Jmeter学习笔记五录制脚本
2.JMeter中级篇-1-JMeter自带的录制功能举例
3.利用Jmeter录制脚本的两种方法
4.录制Jmeter脚本的N种方法
5.JMeter中级篇-2-Firefox录制JMeter脚本的方案
一般来说,使用JMeter进行性能测试不会在GUI模式下进行,GUI图形化界面一般只用来编写测试计划。在GUI模式下调试好测试脚本以后,经过命令行的方式执行测试脚本。
关于JMeter的运行时参数详见Running JMeter
在命令行执行性能测试的经常使用参数:
-n:非GUI模式
-t:指定测试计划文件路径,能够是相对路径或者绝对路径
-l:输出测试结果文件路径,能够是相对路径或者绝对路径
-e:输出测试报告
-o:测试报告保存目录,能够是相对路径或者绝对路径
示例以下:
$ jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz
关于JMeter命令行参数详见:CLI Mode 。
当在单机环境下使用JMeter没法模拟足够的并发量时,可使用分布式模式进行压测。
在分布式模式下,存在一个控制节点Master,多个真正执行测试的从节点Slave,在Master上控制多个Slave进行压力测试。
具体实现:
jmeter -n -t xxx.jmx -r
关于分布式模式运行JMeter详情参考:
JMeter从3.0以后就支持自动生成测试报告,只须要在执行测试时指定参数“-e”和“-o”便可,“-e”参数设置须要自动生成测试报告,“-o”参数指定测试报告目录(该目录不能已经存在)。
举个例子:jmeter -n -t xxx.jmx -l ./yyy.jtl -e -o ./zzz
。
固然,还可使用“-l”参数产生的测试结果文件生成测试报告:jmeter -g ./yyy.jtl -o ./zzz
。
关于JMeter生成测试报告还能够参考以下文章:
1.JMeter-自动生成测试报告
2.Generating Report Dashboard
性能测试中,咱们最关心的指标是吞吐量和响应时间,在JMeter生成的测试报告中,已经很是人性化地展现了这些指标。
这是由APDEX公司推出的表示应用程序性能满意度的指标,值范围为:0-1,所以,满意度越接近1说明应用程序的性能越好。
在实际应用中,这个指标仅仅只能做为应用程序性能的一个很是粗略的判断依据,由于在性能测试过程当中还要考察响应时间的大小。好比:在一次压测过程当中全部请求都获得了响应,此时满意度可能为0.99,可是99%的请求响应时间为1分钟,这显然是不可接受的。
在JMeter生成的测试报告中有一个关于响应时间和吞吐量的统计报告,以下图所示:
首先,须要关注的是99%的请求响应时间(99th pct)统计,会把全部请求的响应时间作统计对比,经过该指标值能够很是明确地知道接口性能是否达标,若是响应时间不知足要求,则须要考虑是否进行优化。
其次,当响应时间符合预期时还能够看到接口的吞吐量(Throughput),即:每秒请求数。
在JMeter性能测试报告中,关于响应时间和吞吐量的统计概要也只是一个很是粗略的参考指标,这个统计数据会受到测试用例在启动和结束时的干扰,更加详细和准确的统计结果应该查看图形化的报表,很是直观。
关于测试结果统计报表的解读能够参考:JMeter-自动生成测试报告
JMeter自带的功能基本能够完成一些常见的性能测试任务,若是须要实现一些功能更增强大的测试,能够经过插件的方式进行扩展。
JMeter安装插件有2种方式:
(1)经过插件管理器下载,实际上JMeter的插件管理器自己也是一个插件,详见:https://jmeter-plugins.org/install/Install/ 。
(2)手动下载,将插件包下载到$JMETER_HOME/lib/ext目录,重启JMeter便可。
1.Concurrency Thread Group
相比起JMeter自带的Thread Group,该插件能够模拟更加真实的用户并发,也能够很方便地对压测时间进行设置。
2.HTTP Raw Request
功能比JMeter自带的Http Request有加强和优化。
3.Raw Data Source
支持从文件中读取数据,这样能够方便造一些压测须要的数据。
4.Transaction Throughput vs Threads
查看线程数与吞吐量的对比关系,能够很是直观地看到系统性能随着并发数的提升而产生的变化。
更多JMeter插件能够从JMeter Plugins下载。
除了丰富的插件,更多关于JMeter的最佳实践能够参考:Best Practices 。
关于对JMeter的扩展,详见:How to write a plugin for JMeter 。
Q1: java.net.NoRouteToHostException: Cannot assign requested address
缘由: 因为linux分配的客户端链接端口用尽,没法创建socket链接所致,虽然socket正常关闭,可是端口不是当即释放,而是处于 TIME_WAIT 状态,默认等待60s后释放。
查看linux支持的客户端链接端口范围,也就是28232个端口。cat /proc/sys/net/ipv4/ip_local_port_range
,端口范围:32768 - 61000
。
解决:
1.调低端口释放后的等待时间,默认为60s,修改成15~30s。echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
2.修改tcp/ip协议配置,经过配置/proc/sys/net/ipv4/tcp_tw_reuse
,默认为0,修改成1,释放TIME_WAIT端口给新链接使用:echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse
3.修改tcp/ip协议配置,快速回收socket资源,默认为0,修改成1。echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle
即总共须要执行以下命令:
$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse $ echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle $ echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
另外,若是非root用户执行上述命令时可能会遇到权限错误:
$ echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied
甚至在命令以前加上sudo
再执行也依然报错:
$ sudo echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse bash: /proc/sys/net/ipv4/tcp_tw_reuse: Permission denied
此时应该经过另外的方式执行:
$ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse' $ sudo bash -c 'echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle' $ sudo bash -c 'echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout'
Q2: 使用JMeter发送POST请求时中文参数在服务器端接收到时为乱码
解决: 在Jmeter中设置“Content-encoding”为:utf-8 。
【参考】
http://www.cnblogs.com/fnng/archive/2012/12/22/2829479.html JMeter基础之一 一个简单的性能测试
https://www.testwo.com/article/357 使用JMeter进行负载测试——终极指南
http://www.cnblogs.com/qmfsun/p/6381767.html JMeter执行压测输出HTML图形化报表(二)
https://my.oschina.net/ydsakyclguozi/blog/536416 Jmeter中的几个重要测试指标释义
https://moonbingbing.gitbooks.io/openresty-best-practices/flame_graph.html 火焰图
https://my.oschina.net/shichangcheng/blog/1560864 JMeter 进行压力测试
https://blog.csdn.net/wwq_1111/article/details/59512546 JMeter压力测试遇到的问题汇总
https://www.infoq.cn/article/k9kx0RxEbhht*iluT9iV 推荐几款经常使用的性能测试工具
https://www.edureka.co/blog/what-is-software-testing/ 涉及软件测试的文章博客
http://blog.csdn.net/lzqinfen/article/details/46326281 JMeter报错the target server failed to respond--JMeter的坑
https://www.jianshu.com/p/130c7fddeddf Jmeter-使用Stepping Thread Group插件来设置负载场景
http://www.cnblogs.com/YatHo/p/6092599.html jmeter压力测试报告 - DEMO