目录
- 性能测试的重要性
- 针对接口的性能测试
- 性能测试基准
- 接口性能测试的主要指标
- abench
- jMeter
- Kelude性能脚本
- 各种监控工具
- 参考
- 总结
性能测试的重要性
众所周知性能测试在软件测试中占有举足轻重的作用,尤其是对于互联网产品这种具有大用户量,大数据量,大并发量特点的产品。如果我们希望产品能够良好的稳定性(Resilience)和可靠性(Reliability),那么我们必须:
- 通过完备的性能测试对我们的产品的性能能力进行全面透彻的评估
- 通过性能测试暴露出系统中的弱点
- 通过性能测试对系统进行合理的优化
性能测试通常会涵盖三个大的部分: - 客户端性能测试
- 针对应用的网络性能测试
- 应用的服务器端性能测试
本文将着重介绍服务器端的性能测试
针对接口的性能测试
无论是C/S结构还是B/S结构,前端的应用都需要通过接口同服务器取得联系,进行数据的交互,最后完成特定的功能。通过对接口的性能测试可以暴露出服务器端的性能质量,数据库读取的性能质量,网络传输的性能等各个方面的问题。
性能测试基准
在进行性能测试之前,通常我们都需要具备一个——基准(Benchmark),这个基准将成为性能测试的一个标准,我们将不同版本的产品的性能测试结果同这个基准(Benchmark)进行比较得到各个版本的性能报告。
为了获得这个基准,我们可以通过基准测试(Benchmark Test BMT),BMT可以认为是一次特殊的性能测试,我们通过设定这次性能测试的环境和各种参数的配置得到这个基准。
例如,我们可以通过一个合理的PV容量结合“2-8原则”推算出并发数,然后用这个并发数作为参数进行性能测试
接口性能测试的主要指标
对于接口的性能测试,有两个指标是至关重要的:
QPS(Query per Second)——每秒查询率
Latency——响应时间
常用性能测试工具的比较
http_load
http_load是基于Linux平台的一种性能测工具。它以并行复用的方式运行,用以测试web服务器的吞吐量与负载,测试web页面的性能。http_load的使用比较简单,可以通过配置参数进行针对http接口的性能测试,http_load的主要参数:
-parallel——并发数
-rate——访问频率
-fetches——访问次数
-seconds——持续访问时间
需要注意的是 parallel和rate,fetches和seconds是要成对出现的
将需要测试的http接口保存在文件中(每行一个url),然后将这个url文件作为参数传给http_load,就可以对想要测试的接口进行性能测试/压力测试(Stress Test)了。为了实现自动化测试,我们可以通过脚本自动运行http_load,为了掌握不同时间段的接口性能差异,我们还可以通过crontab周期性的运行这个http_load的脚本,然后对得到的log进行分析
举一个简单的例子:
#!/bin/sh
{
echo ====Pressure Test with $1 progess and $2 times access====
http_load -parallel $1 -fetches $2 url.txt
echo ====Pressure Test in Rate $4 within $3 seconds access====
http_load -rate $4 -second $3 url.txt
}>>press.log
很容易的我们将得到这样的log结果:
====Pressure Test with 1021 progess and 1000 times access====
1000 fetches, 335 max parallel, 28000 bytes, in 0.049616 seconds
28 mean bytes/connection
20154.8 fetches/sec, 564334 bytes/sec
msecs/connect: 0.131318 mean, 0.398 max, 0.021 min
msecs/first-response: 9.09935 mean, 16.624 max, 0.524 min
HTTP response codes:
code 200 -- 1000
====Pressure Test in Rate 1000 within 100 seconds access====
97727 fetches, 130 max parallel, 2.73636e+06 bytes, in 100 seconds
28 mean bytes/connection
977.27 fetches/sec, 27363.6 bytes/sec
msecs/connect: 0.255355 mean, 21.806 max, 0.022 min
msecs/first-response: 0.618477 mean, 21.806 max, 0.089 min
HTTP response codes:
code 200 -- 97727
可以看到,通过http_load得到的测试结果是非常简陋的,那么有没有一种简便的工具可以得到更多的测试统计结果呢。答案是肯定的。
abench
abench是有Ali开发的结合了http_load和Fbench着两个工具的优点,它消耗的系统资源更小,并且可以提供更加全面的统计数据。
[admin@dn128015 loadtest]$ ./abench17
usage: ./abench_2.0.7_release [-p parallel number] [-r rate(cycletime)]
[-s seconds ] [-f fetches number]
[-k] [–help] [–version]
-p : run with parallel clients [0] 并发client数
-r : make requests each second [0] 每秒请求数,类似于QPS.
-s : run the test for seconds [0] 执行时间,单位是s
-f : run the test for fetches [0] 请求数,有f=r*s
-l : error log file path, default-value:error.log 错误日志文件路径
-a : access log file path 日志路径
-k : enable http keep-alive 保持客户端和服务器的连接,如果已连接上,则在这个连接上发送请求,接收请求。
–help : show help info 帮助信息
–version : show version 版本号
: Directory of query file 查询文件所在的目录
One start specifier, either -parallel or -rate, is required. 开始标识,或-p或-r
One end specifier, either -fetches or -seconds, is required. 结束标识,或-f或-s
and is required.主机名和端口号是必须的
下面是一个简单的应用abench做性能测试的例子,
abench -p 60 -s 100 -o err.log idata.etao.com 80 ~/idata_url
这就是一个abench测试的结果,从这个结果可以发现,abench可以提供比http_load更加丰富的统计数据:
--- FROM(02/19/14 15:00:01) TO(02/19/14 15:10:01) TIME-USED(0h-10min-0s) ---
CMD: abench_2.0.7_release -p 1000 -s 600 s007010.cm6 2088 /home/yuhao.yh/all_url
QPS: 13447.58
Latency: 74.25 ms
Query Success Number: 8068547
Connect Failed Number: 0
Query Failed Number: 100
Query Timeout Number: 0
Match Failed Number: 0
No DocsReturn Number: 8068547 (100.00%)
Average DocsReturn Number: 0.00
No DocsFound Number: 8068547 (100.00%)
Average DocsFound Number: 0.00
Average Return Length(Bytes): 28
Min Response Time: 0.2 ms
Max Response Time: 238.4 ms
25 Percentile: 72.4 ms
50 Percentile: 76.5 ms
75 Percentile: 79.9 ms
90 Percentile: 82.1 ms
95 Percentile: 83.3 ms
99 Percentile: 85.6 ms
同样的我们可以利用脚本将abench的性能测试自动化起来,再此不再赘述。
jMeter
JMeter是Apache组织开发的基于Java的压力测试工具。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。
更多关于jMeter的资料可以访问https://jmeter.apache.org/
在利用jMeter进行http接口的性能测试的时候,我们需要在jMeter的测试模板jmx文件中编辑相应的参数。
例如:
<boolProp name="LoopController.continue_forever">false</boolProp> <intProp name="LoopController.loops">-1</intProp> </elementProp> <stringProp name="ThreadGroup.num_threads">300</stringProp> <stringProp name="ThreadGroup.ramp_time">0</stringProp> <longProp name="ThreadGroup.start_time">1306909102000</longProp> <longProp name="ThreadGroup.end_time">1306909102000</longProp> <boolProp name="ThreadGroup.scheduler">true</boolProp> <stringProp name="ThreadGroup.duration">300</stringProp> <stringProp name="ThreadGroup.delay"></stringProp> </ThreadGroup> <hashTree> <HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="10" enabled="true"> <elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="用户定义的变量" ena bled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="HTTPSampler.domain">idata.etao.com</stringProp> <stringProp name="HTTPSampler.port"></stringProp> <stringProp name="HTTPSampler.connect_timeout">1000</stringProp> <stringProp name="HTTPSampler.response_timeout">2000</stringProp> <stringProp name="HTTPSampler.protocol"></stringProp> <stringProp name="HTTPSampler.contentEncoding"></stringProp> <stringProp name="HTTPSampler.path">${para}</stringProp> <stringProp name="HTTPSampler.method">GET</stringProp> <boolProp name="HTTPSampler.follow_redirects">false</boolProp> <boolProp name="HTTPSampler.auto_redirects">true</boolProp> <boolProp name="HTTPSampler.use_keepalive">true</boolProp> <boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp> <stringProp name="HTTPSampler.implementation">Java</stringProp> <boolProp name="HTTPSampler.monitor">false</boolProp> <stringProp name="HTTPSampler.embedded_url_re"></stringProp> </HTTPSamplerProxy> <hashTree/>
其中
300
300
是并发数
300
300
是测试时间
jMeter的测试结果是一个jtl文件,里面关于针对接口测试的各种数据:
<?xml version="1.0" encoding="UTF-8"?>
<testResults version="1.2">
<httpSample t="89" lt="89" ts="1394390708742" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-58" dt="text" by="10361"/>
<httpSample t="61" lt="57" ts="1394390708774" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-91" dt="text" by="52286"/>
<httpSample t="83" lt="83" ts="1394390708749" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-66" dt="text" by="10637"/>
<httpSample t="81" lt="81" ts="1394390708757" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-77" dt="text" by="10361"/>
<httpSample t="74" lt="70" ts="1394390708765" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-89" dt="text" by="52286"/>
<httpSample t="91" lt="87" ts="1394390708749" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-68" dt="text" by="52286"/>
<httpSample t="95" lt="94" ts="1394390708746" s="true" lb="10" rc="200" rm="OK" tn="/idata 1-64" dt="text" by="10361"/>
其中:
t——全部访问完成的时间,单位毫秒
lt——从发出请求到获得第一个返回的数据包的时间,单位毫秒
ts——发起访问的timestamp
s——访问结果
rc——http返回值代码
可以通过脚本对结果文件进行分析获得整个测试的统计结果:
java -jar ~/JTLParser.jar --jtlFile $MYDIR/result.jtl
========Test result for updatetime=currenttime,src=all========
FROM: 03/09/14 02:40:03
END: 03/09/14 02:45:03
Sended Query Number: 131846
Total Spended Time(s): 299.95
QPS: 439.56
Latency(ms): 124
Max Response Time(ms): 2022
Query Success Number: 131840
Query Failed Number: 6
Kelude性能脚本
Kelude是一套功能强大的集成化工具,利用它上面的PAP脚本,可以通过脚本创建向导非常简便的创建性能测试脚本,然后利用Kelude可以简便的配置测试环境和参数,自动的规划测试执行时间,并且统计测试结果。
下面通过一个简单的例子说明如何利用PAP脚本进行针对http接口的性能测试。
创建PAP性能脚本
- 打开后端性能-性能脚本,然后点击——“新增脚本”按钮
- 选择脚本类型,添加脚本名称,然后就可以添加事务了。
- 将你要测试的http接口作为事务添加到脚本中,如果需要对你要测试的host进行绑定,可以添加域名绑定
将各项参数加好之后就可以保存,完成性能脚本了。 - 创建性能场景,在这里可以配置并发用户数
- 创建性能任务,在这一步就可以将刚才创建的性能脚本,性能场景整合成一个性能任务了,然后指定这个性能任务的开始时间,持续时间。就可以等着收结果了
在性能任务运行成功之后,可以点击任务查看测试结果详情:
各种监控工具
在性能测试的时候,系统的诸多性能是必须要加以关注的,以免由于性能测试参数的选择不当对系统造成损坏。所以我们再进行性能测试/压力测试的时候要通过各种监控工具对我们加压的系统加以关注。同时利用这些监控工具,我们以可以对他们的数据进行采集,将这些数据作为我们性能测试分析报告的一部分。
参考
- iperf3: 用来测量一个网络最大带宽的工具
总结
在这里对几种常用的http接口的性能测试工具进行了非常粗浅的罗列。性能测试作为系统测试中至关重要的一个环节,需要针对被测对象的特性合理的选择测试工具和测试方法。同时性能测试又是一个自动化程度最高的一个测试门类。这就给我们带来个更大的挑战和发挥空间。希望有机会和大家共同探讨更多的关于性能测试的知识。