阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

ab和JMeter进行GET/POST压力测试的使用心得和比较

185次阅读
没有评论

共计 8348 个字符,预计需要花费 21 分钟才能阅读完成。

引言:互联网服务压测是非常重要的评价方法,ab,webbench,jmeter 等都是业界流行的测试工具,ab 和 webbench 作为 shell 模式下轻量级的测试工具,jmeter 则作为有 GUI 界面的更高级测试工具,各有特点,ab 比 webbench 功能更多一些,所以这里选择 ab 和 jmeter 来做一个对比。

【测试环境的安装】
【ab】

ab 就是 Apache Benchmark 的缩写,顾名思义它是 Apache 组织开发的一款 web 压力测试工具,优点是使用方便,统计功能强大。

ab 作为一款非常流行的压测工具,使用细节这里就不多介绍了,直接给出个人的使用体会:

首先是安装,Ubuntu 和 CentOS 目前都提供自动安装命令(至少 ubuntu 14,centos 6 可以)

ubuntu:sudo apt-get install apache2-utils

centos:yum install httpd-tools

安装好之后就可以开始进行测试。

ab 一般常用参数就是 -n,-t,和 -c。

-c(concurrency)表示用多少并发来进行测试;

- t 表示测试持续多长时间;

- n 表示要发送多少次测试请求。

一般 - t 或者 - n 选一个用。

对于模拟 GET 请求进行测试,ab 非常简单,就是:ab -n 100 -c 10 ‘http://testurl.com/xxxx?para1=aaa&para2=bbb’

对于模拟 POST 请求进行测试,则稍微复杂些,需要把将要 post 的数据(一般是 json 格式)放在文件里。比如一个 post 接口需要如下方式访问

curl -H ‘Content-Type:application/json’ -X POST  -d ‘{“actionType”:”collect”,”appId”:1,”contentId”:”1770730744″,”contentType”:”musictrack”,”did”:”866479025346031″,”endType”:”mobile”,”recommendId”:”104169490_1_0_1434453099#1770730744#musictrack#USER_TO_SONG_TO_SONGS#gsql_similarity_content2content”,”tabId”:0,”uid”:”104169490″}’ http://localhost:8083/query/leui/v0/post/user/behavior/content

需要吧 -d 后面的 json 数据放在一个文件里,比如建立一个文件 post_data.txt,放入:

{“actionType”:”collect”,”appId”:1,”contentId”:”1770730744″,”contentType”:”musictrack”,”did”:”866479025346031″,”endType”:”mobile”,”recommendId”:”104169490_1_0_1434453099#1770730744#musictrack#USER_TO_SONG_TO_SONGS#gsql_similarity_content2content”,”tabId”:0,”uid”:”104169490″}

然后用 - p 参数解析并发送这个 json 数据:ab -n 100 -c 10 -p post_data.txt -T ‘application/json’ http://localhost:8083/query/leui/v0/post/user/behavior/content

【Jmeter】
jmeter 是一个非常强大和用户友好的 GUI 工具,http 访问的参数设置基本应有尽有,软件的 help 里的用户手册图例比较丰富,对于初学者来说很好上手

对于 http 测试的可配置参数有(1)http 请求配置:测试目标 host,端口,url 路径,http 请求参数,post 的数据,http header(2)测试全局策略:测试发送的并发量,测试循环次数(jmeter 没有测试时间的设定,只有不断发送测试请求反复重复多少次 loop,或者无限重复)。对于(1)里每个可配置的参数都可以用变量 ${varaible_name} 来代替,而 araiable 可以来自 CSV 格式的外部输入,GUI 有“测试计划(test plan)右键点击 —– 添加 —– 配置元件 —–CSV Data Set Config 里可以设置 CSV 文件来源和 CSV 里每列数据对应的变量名称。

上面说的功能还有其他强大功能设置,在 help 文档和很多网上资料里都有详细介绍, 比如 CSV 输入设置(博客),这里不再赘述。

一般来说,主要用到以下设置界面

新建测试计划(Test Plan)

Test Plan —- 新建 Thread Group(线程组)

线程组 —- 配置元件 —-HTTP Header Manager

线程组 —– 配置元件 —CSV Data Set Config

线程组 —sampler(采样器)—–HTTP 请求,这里面有两个 tab,一个是“parameters“tab,配置 http 请求参数,一个是“post data”tab,可配置 post 的数据,一般是一个 json 串,json 串里的字段都可以用 ${xxx} 这样的变量来表示。

这几个界面配置好即可,而且 jmeter 的配置保存时会生成.jmx 文件,这个不只是用来保存修改配置用,而且还有一个更大的用处,就是在非 GUI(命令行,shell)下运行。

因为我们的压测环境往往是 linux 系统,而且为了最大程度的发挥压测工具的性能,不论系统还是压测工具都最好运行在非 GUI 模式

linuxshell 下,因为 jmeter 是 Java 开发的,无需安装,只需要把 jmeter 解压后,在解压路径下,运行

{jmeter_install_dir)/}bin/jmeter -n -t $target -l xxxx.jtl

-n 就是静默模;

-t 后面就跟.jmx 配置文件的路径;

-l 跟一个输出文件用于记录每次请求的时间,可以用 jmeter GUI 打开生成最终统计聚合报告。

在命令行模式下运行 jmeter,还可以从命令行(shell)输入参数,只要在 jmeter 命令后的参数列表里加上  -JXXXX = value , XXXX 被 jmeter 识别为一个外部输入变量,其值是 value,在 jmerter 配置里用 ${__P(XXXX)} 来使用这个外部输入变量,注意 ”__P” 开头是连着的两个下划线。

【测试构建和效果对比】

下面我们用一个实际的例子来进行 ab 和 jmeter 压力测试的效果对比, 首先是 GET 请求。

【ab】

先用 10 个并发压测 100 秒。

]# ab -t 100 -c 10 ‘http://localhost:8083/xxxx?uid=1233435&did=123456789&appId=1’

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking xxx.xxx.xxx.xxx (be patient)
Finished 733 requests

Server Software:        CppCMS-Embedded/1.0.4
Server Hostname:      xxx.xxx.xxx.xxx
Server Port:            8083

Document Path:        / xxx?uid=79057533&did=123456789&appId=1
Document Length:        4601 bytes

Concurrency Level:      10
Time taken for tests:  100.137 seconds
Complete requests:      733
Failed requests:        732
  (Connect: 0, Receive: 0, Length: 732, Exceptions: 0)
Write errors:          0
Total transferred:      3672653 bytes
HTML transferred:      3572232 bytes
Requests per second:    7.32 [#/sec] (mean)
Time per request:      1366.124 [ms] (mean)
Time per request:      136.612 [ms] (mean, across all concurrent requests)
Transfer rate:          35.82 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median  max
Connect:        1    2  2.4      2      40
Processing:  342 1352 636.3  1183    6046
Waiting:      342 1351 636.2  1183    6046
Total:        345 1354 636.8  1186    6049

Percentage of the requests served within a certain time (ms)
  50%  1185
  66%  1333
  75%  1460
  80%  1564
  90%  1835
  95%  2357
  98%  3248
  99%  5205
 100%  6049 (longest request)

【jmeter】

再用 jemeter 以同样的配置(Thread 数 为 10,ramp 时间为 1 秒,超时阈值为 3000ms)

运行结果如下:
Creating summariser <summary>
Created the tree successfully using music_api_uid.jmx
Starting the test @ Thu Nov 19 11:19:43 CST 2015 (1447903183454)
Waiting for possible shutdown message on port 4445
summary +    90 in    16s =    5.7/s Avg:  1677 Min:  959 Max:  3757 Err:    0 (0.00%) Active: 10 Started: 10 Finished: 0
summary +    202 in  31.1s =    6.5/s Avg:  1477 Min:  912 Max:  2727 Err:    0 (0.00%) Active: 10 Started: 10 Finished: 0
summary =    292 in    46s =    6.4/s Avg:  1539 Min:  912 Max:  3757 Err:    0 (0.00%)
summary +    164 in    31s =    5.3/s Avg:  1830 Min:  972 Max:  5009 Err:    5 (3.05%) Active: 10 Started: 10 Finished: 0
summary =    456 in    76s =    6.0/s Avg:  1643 Min:  912 Max:  5009 Err:    5 (1.10

最终通过 GUI 打开请求详细记录,生成聚合报告的结果为

samples: 576

average: 1713

median: 1496

90% Line: 2353

min: 912

max: 5009

throught: 5.8/sec

kb/sec: 27.8

error%: 2.08%

GET API 压测结果对比

abjmeter
发送总请求数 733576
平均请求时间 (ms)13661713
请求时间中位数(50%<)(ms)11851496
请求时间 90%< (ms)18352353
error 2.08%
QPS7.326

对比两次测试,ab 完成了 733 次,而 jmeter 完成了 576 次而 ab 完成了 733 次,其实这个数据不算准确,因为 jmeter 不支持精确的测试时间的限制,所以我是按时强制终止了 jemeter,所以有些请求可能就被漏掉了。不过我后来测试了同样总请求数时(ab 用 - n 设置,jmeter 则用 thread*loops 来设置),jmeter 也比 ab 慢戈 15%,可能和 jmeter 自己要做很多统计有关系。

因为测试时间不是严格相等,所以主要看平均:时间分布,ab 普遍低一些。双方测试环境和测试参数都一致,不知道是不是 jmeter 在计算返回时间上算法不一样。平均时间,jmeter 统计口径也是偏高

我留了个心眼,查询了 web 接口后台日志,确保了两次测试的传参是一样的,那么结果的差别只能理解为两个软件在统计口径(比如返回时件的测量标准上),以及 http 访问方式上有差别 (比如同样是设置 10 个并发,一般是理解为开 10 个线程去不断的请求接口,但线程的调度策略不一样,对服务器的压力不一样,返回的性能也不一样)。

GET 测试对比完,再来对比一下 POST API 测试的效果:

【ab】:

#ab -t 100 -c 10 -p post_data.txt -T ‘application/json’ http://localhost:8083/xxxxx

This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking xxx.xxx.xxx.xxx (be patient)
Completed 5000 requests
Completed 10000 requests
Finished 12937 requests

Server Software:        CppCMS-Embedded/1.0.4
Server Hostname:        xxx.xxx.xxx.xxx
Server Port:            8083

Document Path:          /xxxxx
Document Length:        92 bytes

Concurrency Level:      10
Time taken for tests:  100.001 seconds
Complete requests:      12937
Failed requests:        0
Write errors:          0
Total transferred:      2962573 bytes
Total POSTed:          4828858
HTML transferred:      1190204 bytes
Requests per second:    129.37 [#/sec] (mean)
Time per request:      77.299 [ms] (mean)
Time per request:      7.730 [ms] (mean, across all concurrent requests)
Transfer rate:          28.93 [Kbytes/sec] received
                        47.16 kb/s sent
                        76.09 kb/s total

Connection Times (ms)
              min  mean[+/-sd] median  max
Connect:        1    2  8.9      1    1001
Processing:    31  76  78.5    69    2452
Waiting:      31  75  77.7    69    2452
Total:        33  77  79.0    71    2454

Percentage of the requests served within a certain time (ms)
  50%    71
  66%    80
  75%    88
  80%    91
  90%    101
  95%    113
  98%    124
  99%    140
 100%  2454 (longest request)

【jmeter】

而同样参数配置的 jmeter 的结果为:

#../apache-jmeter-2.11/bin/jmeter -n -t post.jmx -JCSV=post_paras.txt -JIP=xxx.xxx.xxx.xxx -JPORT=8083 -JTHREAD=10 -JRAMP=1 -l “post_test.log”

Creating summariser <summary>
Created the tree successfully using post_to_recommend_user_action_server.jmx
Starting the test @ Tue Nov 17 20:49:37 CST 2015 (1447764577991)
Waiting for possible shutdown message on port 4445
summary +  3978 in  21.1s =  188.5/s Avg:    51 Min:    32 Max:  1049 Err:    0 (0.00%) Active: 10 Started: 10 Finished: 0
summary +  3796 in  30.1s =  126.2/s Avg:    78 Min:    34 Max:  1596 Err:    0 (0.00%) Active: 10 Started: 10 Finished: 0
summary =  7774 in  51.1s =  152.1/s Avg:    64 Min:    32 Max:  1596 Err:    0 (0.00%)
summary +  3273 in  30.1s =  108.8/s Avg:    91 Min:    37 Max:  3091 Err:    1 (0.03%) Active: 10 Started: 10 Finished: 0
summary =  11047 in  81.1s =  136.2/s Avg:    72 Min:    32 Max:  3091 Err:    1 (0.01%)

对 post_test.log 进行聚合报告分析

samples: 11899 

average: 58

median: 52

90% line: 76

min: 27

max: 3091

error: 0.01%

throughout: 7.6/sec

kb/sec: 1.9

post api 压测结果对比

abjmeter
完成请求数 1293711899
平均返回时间(ms)7758
最大返回时间(ms) 3091
最小返回时间(ms) 27
请求时间中位数 (50%<)7152
90% 的请求反水时间低于(ms)10176
错误率(基本是超时)00.01%
QPS129136

【使用对比总结】
个人体会是:

统计效果上,ab 占优:ab 的优点是统计的结果可读性更强更能帮助人分析,至于一些参数的差异,主要看源代码实现了,但误差在可接受的范围内,作为压力测试,我们需要的是服务器面对压力的一个大致的能力和随着压力增大后服务器性能的变化趋势,所以 ab 和 jmeter 两个数字谁更精确是没太多意义的,反而是他俩数字差别不大就已经起到了互相印证的作用。

压测方案指定上,jmeter 占优:主要是 jmeter 支持可变参数和 CSV 数据集的输入,能设定更复杂的测试样例,适用范围更广。

ab 不需要写配置文件,只需要几个命令行参数就能执行压测,适用于接口简单业务逻辑简单的 http 服务的测试。

使用 JMeter 对 WebService 进行压力测试 http://www.linuxidc.com/Linux/2014-10/108088.htm

Windows 下 JMeter 安装手记 http://www.linuxidc.com/Linux/2013-10/91749.htm

使用 JMeter 进行基本压力测试 http://www.linuxidc.com/Linux/2013-04/83086.htm

JMeter 中断言的使用方法 http://www.linuxidc.com/Linux/2013-10/91770.htm

JMeter 监控插件 JMeterPlugins&PerfMon 安装  http://www.linuxidc.com/Linux/2016-05/131684.htm

JMeter 的详细介绍 :请点这里
JMeter 的下载地址 :请点这里

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-07/133191.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计8348字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中