wrk,ab,locust,Jmeter 壓測結果比較

背景:

項目須要對一批接口進行壓測,要求是接口的QPS(Quest Per Second每秒請求數)達到6萬以上
因爲樓主一直使用的壓力測試工具是jmeter,可是jmeter單臺電腦沒法達到6萬的QPS,因而使用網傳比較好用的其餘性能工具進行壓測比較,選出一款符合要求的工具進行壓測。html

壓測機器:Linux 4核8G
因爲不一樣的性能工具壓測時消耗的系統資源不同,防止系統資源形成的干擾,測試時服務器只運行壓測工具,且非本機壓本機。java

示例接口,post請求,請求body可爲空
POST https://api.midukanshu.com/logstash/userbehavior/report
返回:
{"code":0,"message":"成功","currentTime":1543386393,"data":[]}python

1、 Wrk

wrk是一款現代化的HTTP性能測試工具,即便運行在單核CPU上也能產生顯著的壓力。最大的優勢是它支持多線程,這樣更容易發揮多核 CPU 的能力,從而更容易測試出系統的極限能力。nginx

安裝

git clone https://github.com/wg/wrk.git
cd wrk/
makegit

查看版本

./wrk -vgithub

 

 

參數說明

-c:總的鏈接數(每一個線程處理的鏈接數=總鏈接數/線程數)
-d:測試的持續時間,如2s(2second)2m(2minute)2h(hour),默認爲s
-t:須要執行的線程總數,默認爲2,通常線程數不宜過多. 核數的24倍足夠了. 多了反而由於線程切換過多形成效率下降
-s:執行Lua腳本,這裏寫lua腳本的路徑和名稱,後面會給出案例
-H:須要添加的頭信息,注意header的語法,舉例,-H token: abcdef
timeout:超時的時間
latency:顯示延遲統計信息

返回結果

Latency:響應時間
Req/Sec:每一個線程每秒鐘的執行的鏈接數
Avg:平均
Max:最大
Stdev:標準差
+/- Stdev正負一個標準差佔比
Requests/sec:每秒請求數(也就是QPS),等於總請求數/測試總耗時
Latency Distribution,若是命名中添加了—latency就會出現相關信息

運行

./wrk -t 5 -c 300 -d 60 --latency https://api.midukanshu.com/logstash/userbehavior/createweb

 


300個鏈接數跑60秒:Request/sec(每秒請求數):3322.48apache

 

./wrk -t 5 -c 500 -d 60 --latency https://api.midukanshu.com/logstash/userbehavior/createapi

 


500個鏈接數跑60秒:Request/sec(每秒請求數):3321.67緩存

 

可見鏈接數從300加到500,QPS沒有明顯變化,就沒有再往上加的必要了,再加也只會花更多的時間去坐線程的切換,QPS不必定上升,並且300個鏈接數時CPU已經跑滿,後面會有截圖說明

若是post請求的body不爲空則指定lua文件進行讀取,示例以下:
./wrk -t 5 -c 300 -d 60 --script=post.lua --latency https://api.midukanshu.com/logstash/userbehavior/create
post.lua文件內容
wrk.method = "POST"
wrk.body = ""
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

2、 Apache Benchmark

Apache Benchmark簡稱 ab,是apache自帶的壓力測試工具

安裝:

sudo yum install httpd-tools

查看版本:

ab -V

 

 

參數說明

-n 表示請求總數(-t參數可任選其一)
-c 表示併發數
-t 標識請求時間
-p:模擬post請求,文件格式爲gid=2&status=1,配合-T使用
-T:post數據所使用的Content-Type頭信息,如-T 'application/x-www-form-urlencoded'

返回結果

Server Software: nginx/1.13.6 #測試服務器的名字
Server Hostname: api.midukanshu.com #請求的URL主機名
Server Port: 443 #web服務器監聽的端口

Document Path: /logstash/userbehavior/create   #請求的URL中的根絕對路徑
Document Length: 0 bytes #HTTP響應數據的正文長度

Concurrency Level: 300        # 併發用戶數,這是咱們設置的參數之一
Time taken for tests: 22.895 seconds #全部這些請求被處理完成所花費的總時間
Complete requests: 50000        # 總請求數量,這是咱們設置的參數之一
Failed requests: 99         # 表示失敗的請求數量,這裏的失敗是指請求在鏈接服務器、發送數據等環節發生異常,以及無響應後超時的狀況
Write errors: 0
Total transferred: 96200 bytes    #全部請求的響應數據長度總和。包括每一個HTTP響應數據的頭信息和正文數據的長度
HTML transferred: 79900 bytes    # 全部請求的響應數據中正文數據的總和,也就是減去了Total transferredHTTP響應數據中的頭信息的長度
Requests per second: 2183.91 [#/sec] (mean) #吞吐率,計算公式:Complete requests/Time taken for tests 總請求數/處理完成這些請求數所花費的時間
Time per request: 137.368 [ms] (mean) # 用戶平均請求等待時間,計算公式:Time token for tests/Complete requests/Concurrency Level)。處理完成全部請求數所花費的時間/(總請求數/併發用戶數)
Time per request: 0.458 [ms] (mean, across all concurrent requests) #服務器平均請求等待時間,計算公式:Time taken for tests/Complete requests,正好是吞吐率的倒數。也能夠這麼統計:Time per request/Concurrency Level
Transfer rate: 652.50 [Kbytes/sec] received #表示這些請求在單位時間內從服務器獲取的數據長度,計算公式:Total trnasferred/ Time taken for tests,這個統計很好的說明服務器的處理能力達到極限時,其出口寬帶的需求量。

運行

ab -c 300 -t 60 https://api.midukanshu.com/logstash/userbehavior/create

 

 

300線程跑60秒:Requests per second=2301.68

ab -c 500 -t 60 https://api.midukanshu.com/logstash/userbehavior/create

 

 

500線程跑60秒:Requests per second=2279.27

可見線程數加到500,還不如300的了,因此有時候線程數不是加的越高越好,更根據服務器的配置,CPU,IO,帶寬等的消耗設置合理的線程數
細心的讀者可能看出,我雖然設置了-t參數爲60s,但實際只運行了20多秒,由於ab跑滿50000個request就本身停了,想跑夠60s可使用-n參數

若是post請求的body不爲空則指定文件進行讀取,示例以下:
ab -n 100 -c 10 -p 'post.txt' -T 'application/x-www-form-urlencoded' 'http://test.api.com/ttk/auth/info/'
post.txt文件內容
devices=4&status=1

3、 Locust

Locust是一個Python編寫的分佈式的性能測試工具

安裝

安裝python pip
sudo yum -y install python-pip
經過Python自帶的pip安裝locust
pip install locustio

查看版本:

locust –version

 

 

參數說明

--host指定被測試的主機,採用以格式:http://192.168.21.25
-f指定運行 Locust 性能測試文件,默認爲: locustfile.py
-no-web no-web 模式運行測試,須要 -c -r 配合使用
-c指定併發用戶數,做用於 no-web 模式。
-r指定每秒啓動的用戶數,做用於 no-web 模式。
-t設置運行時間, 例如: (300s, 20m, 3h, 1h30m). 做用於 no-web 模式。

返回結果

Name:請求方式,請求路徑;
reqs:當前請求的數量;
fails:當前請求失敗的數量;
Avg:全部請求的平均響應時間,毫秒;
Min:請求的最小的服務器響應時間,毫秒;
Max:請求的最大服務器響應時間,毫秒;
Median:中間值,單位毫秒;
req/s:每秒鐘請求的個數。
Total:各接口的彙總信息

運行:
Locust_demo.py文件內容

# coding=utf-8
from locust import HttpLocust, TaskSet, task
class UserBehavior(TaskSet):

@task(1)
def profile(self):
self.client.post("/logstash/userbehavior/report", {})

class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait = 0
max_wait = 0

locust -f locust_demo.py --host=https://api.midukanshu.com --no-web -c 300 -t 60s

 


300線程跑60秒:Req/s=730.10

 

locust -f locust_demo.py --host=https://api.midukanshu.com --no-web -c 500 -t 60s

 


500線程跑60秒:Req/s=741.50

 

4、 Jmeter

Apache JMeter是Apache組織開發的基於Java的壓力測試工具

安裝

安裝jdk:yum -y list java
yum install -y java-1.8.0-openjdk-devel.x86_64
配置Java環境變量後執行java -version

 

 

下載:apache-jmeter-3.2.tgz
而後解壓到當前傳的目錄
tar zxvf apache-jmeter-3.2.tgz jmeter

查看版本:

見jmeter主目錄

參數說明:

-n : GUI 模式執行JMeter
-t : 執行測試文件所在的位置及文件名
-r : 遠程將全部agent啓動,用在分佈式測試場景下,不是分佈式測試只是單點就不須要-r
-l : 指定生成測試結果的保存文件, jtl 文件格式
-e : 測試結束後,生成測試報告
-o : 指定測試報告的存放位置

返回結果:

Avg:全部請求的平均響應時間,毫秒;
Min:請求的最小的服務器響應時間,毫秒;
Max:請求的最大服務器響應時間,毫秒;
Err:請求錯誤個數,錯誤百分率;
Active:激活的線程數,當Active=0,則說明運行中的線程數爲0,則壓測結束。
Started:啓動的線程數
Finished:完成的線程數

運行腳本:

./jmeter.sh -n -t ./jmx/userbehavior_report.jmx
300個線程跑60秒:

 

 

Summary + 398526 in 00:00:18 =21959.8/s
Summary = 1018846 in 00:01:04 =15904.6/s
Summary =表示總共運行1分04秒,請求了1018846個接口,這1分04秒內的QPS=15904.6/s
Summary +表示統計最近18秒,請求了398526個接口,即00:00:46到00:01:04期間的18秒,QPS=21959.8/s
500個線程跑60秒:
到這差很少了,500線程跑出來也沒300的QPS高,就不放圖了

總結:
300線程跑60秒, 對比各壓測工具的 QPS:
Wrk=3322.48/s
Ab=2301.68/s
Locust= 730.10/s
Jmeter=21959.8/s
我曾覺得的壓測結果是:wrk > ab > locust > jmeter
實際結果是:jmeter > wrk > ab > locust

5、資源消耗對比

Top參數解釋:

cpu狀態
6.7% us 用戶空間佔用CPU的百分比。
0.4% sy 內核空間佔用CPU的百分比。
0.0% ni 改變過優先級的進程佔用CPU的百分比
92.9% id 空閒CPU百分比
0.0% wa IO等待佔用CPU的百分比
0.0% hi 硬中斷(Hardware IRQ)佔用CPU的百分比
0.0% si 軟中斷(Software Interrupts)佔用CPU的百分比
內存狀態
8306544k total 物理內存總量(8GB
7775876k used 使用中的內存總量(7.7GB
530668k free 空閒內存總量(530M
79236k buffers 緩存的內存量 79M
各進程(任務)的狀態監控
PID 進程id
USER 進程全部者
PR 進程優先級
NI nice值。負值表示高優先級,正值表示低優先級
VIRT 進程使用的虛擬內存總量,單位kbVIRT=SWAP+RES
RES 進程使用的、未被換出的物理內存大小,單位kbRES=CODE+DATA
SHR 共享內存大小,單位kb
S 進程狀態。D=不可中斷的睡眠狀態 R=運行 S=睡眠 T=跟蹤/中止 Z=殭屍進程
%CPU 上次更新到如今的CPU時間佔用百分比
%MEM 進程使用的物理內存百分比
TIME+ 進程使用的CPU時間總計,單位1/100
COMMAND 進程名稱(命令名/命令行)

在top基本視圖中,按鍵盤數字「1」,可監控每一個邏輯CPU的情況:
可看出壓測服務器有4個邏輯CPU

 

 

300線程跑60秒CPU消耗如圖:
Wrk=377.1%
Ab=99.7%
Locust= 100%
Jmeter=396.4%
若是服務器是多核CPU可能在下方看到有些進程CPU佔用超過100%,這種通常是該進程使用了多核。
能夠看出wrk和jmeter都超過100%,且jmeter的396/4=99%,即便用了服務器99%的性能,
在壓力測試過程當中,最好時刻留意哪些資源成爲了瓶頸,好比:CPU 是否是跑滿了,IO 是否是跑滿了
查看0.0 wa這裏,IO等待所佔用的CPU時間的百分比,高過30%時IO壓力高。

比較結果:

工具 wrk ab locust jmeter
安裝 簡單 簡單 依賴python 依賴jdk
場景壓測 不支持 不支持 支持 支持
UI界面
腳本錄製 利用本地ProxyServer或badboy
資源監控 經過JMeterPlugins插件和ServerAgent實現
報告分析 生成HTML報告

雖然jmeter提供UI界面,可是其壓測腳本也依賴UI界面,致使其沒法在Linux服務器上直接編輯寫腳本,只有編寫好腳本後再傳到Linux服務器。
關於對於壓測工具的選擇

若是你想作場景的壓測,而不是單個接口的壓測
可以使用jmeter或locust,支持接口串聯,接口body參數化,思考時間等複雜場景
若是你壓測要求的併發比較高,須要使用分佈式壓測
可以使用jmeter或locust
若是你關注接口的返回,多維度壓測報告統計
jmeter,jmeter,jmeter
若是想盡快編寫接口,只關注接口的發送,形成的QPS和錯誤率
可以使用wrk或ab
實踐中也能夠選擇本身熟悉的壓測工具

因爲單臺4核8G服務器對待測接口最高能形成2萬的QPS,仍是距離我須要的6萬還有必定距離,這時候可使用Jmeter的分佈式壓測

固然還有更多我還沒了解到的優秀壓測工具,壓測結果存在必定侷限,僅供參考
歡迎交流指正,感謝閱讀。

原文出處:https://www.cnblogs.com/grizz/p/11570801.html

相關文章
相關標籤/搜索