引言: 互聯網服務壓測是很是重要的評價方法,ab,webbench,jmeter等都是業界流行的測試工具,ab和webbench做爲shell模式下輕量級的測試工具,jmeter則做爲有GUI界面的更高級測試工具,各有特色,ab比webbench功能更多一些,因此這裏選擇ab和jmeter來作一個對比。java
ab就是Apache Benchmark的縮寫,顧名思義它是Apache組織開發的一款web壓力測試工具,優勢是使用方便,統計功能強大。linux
ab做爲一款很是流行的壓測工具,使用細節這裏就很少介紹了,直接給出我的的使用體會:web
首先是安裝,ubuntu和centos目前都提供自動安裝命令 (至少ubuntu 14, centos 6能夠)算法
ubuntu:sudo apt-get install apache2-utils sql
centos:yum install httpd-tools
shell
安裝好以後就能夠開始進行測試。apache
ab通常經常使用參數就是 -n, -t ,和 -c。json
-c(concurrency)表示用多少併發來進行測試;ubuntu
-t表示測試持續多長時間;centos
-n表示要發送多少次測試請求。
通常-t或者-n選一個用。
對於模擬GET請求進行測試,ab很是簡單,就是:ab -n 100 -c 10 'http://testurl.com/xxxx?para1=aaa¶2=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是一個很是強大和用戶友好的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請求。
先用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)
再用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%
ab | jmeter | |
發送總請求數 | 733 | 576 |
平均請求時間(ms) | 1366 | 1713 |
請求時間中位數(50%<)(ms) | 1185 | 1496 |
請求時間90%< (ms) | 1835 | 2353 |
error | 2.08% | |
QPS | 7.32 | 6 |
對比兩次測試,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 -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的結果爲:
#../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
ab | jmeter | |
完成請求數 | 12937 | 11899 |
平均返回時間(ms) | 77 | 58 |
最大返回時間(ms) | 3091 | |
最小返回時間(ms) | 27 | |
請求時間中位數(50%<) | 71 | 52 |
90%的請求反水時間低於(ms) | 101 | 76 |
錯誤率(基本是超時) | 0 | 0.01% |
QPS | 129 | 136 |
我的體會是:
統計效果上,ab佔優:ab的優勢是統計的結果可讀性更強更能幫助人分析,至於一些參數的差別,主要看源代碼實現了,但偏差在可接受的範圍內,做爲壓力測試,咱們須要的是服務器面對壓力的一個大體的能力和隨着壓力增大後服務器性能的變化趨勢,因此ab和jmeter兩個數字誰更精確是沒太多意義的,反而是他倆數字差異不大就已經起到了互相印證的做用。
壓測方案指定上,jmeter佔優:主要是jmeter支持可變參數和CSV數據集的輸入,能設定更復雜的測試樣例,適用範圍更廣。
ab不須要寫配置文件,只須要幾個命令行參數就能執行壓測,適用於接口簡單業務邏輯簡單的http服務的測試。