1. 程式人生 > >效能測試工具 wrk,ab,locust,Jmeter 壓測結果比較

效能測試工具 wrk,ab,locust,Jmeter 壓測結果比較

背景:

專案需要對一批介面進行壓測,要求是介面的QPS(Quest Per Second每秒請求數)達到6萬以上
由於樓主一直使用的壓力測試工具是jmeter,但是jmeter單臺電腦無法達到6萬的QPS,於是使用網傳比較好用的其他效能工具進行壓測比較,選出一款符合要求的工具進行壓測。

壓測機器:Linux 4核8G
由於不同的效能工具壓測時消耗的系統資源不一樣,防止系統資源造成的干擾,測試時伺服器只執行壓測工具,且非本機壓本機。

示例介面,post請求,請求body可為空
POST https://api.midukanshu.com/logstash/userbehavior/report


返回:
{“code”:0,“message”:“成功”,“currentTime”:1543386393,“data”:[]}

一、 Wrk
wrk是一款現代化的HTTP效能測試工具,即使執行在單核CPU上也能產生顯著的壓力。最大的優點是它支援多執行緒,這樣更容易發揮多核 CPU 的能力,從而更容易測試出系統的極限能力。

安裝
git clone https://github.com/wg/wrk.git
cd wrk/
make

檢視版本
./wrk -v
在這裡插入圖片描述
引數說明

-c:總的連線數(每個執行緒處理的連線數=總連線數/執行緒數)
-d:測試的持續時間,如2s(2second),2m(2minute),2h(hour),預設為s
-t:需要執行的執行緒總數,預設為2,一般執行緒數不宜過多. 核數的2到4倍足夠了. 多了反而因為執行緒切換過多造成效率降低
-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/create
在這裡插入圖片描述
300個連線數跑60秒:Request/sec(每秒請求數):3322.48

./wrk -t 5 -c 500 -d 60 --latency https://api.midukanshu.com/logstash/userbehavior/create
在這裡插入圖片描述
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”
二、 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 transferred中HTTP響應資料中的頭資訊的長度
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

跟大家推薦一個學習資料分享群:903217991,裡面大牛已經為我們整理好了許多的學習資料,有自動化,介面,效能等等的學習資料!人生是一個逆水行舟的過程,不進則退,咱們一起加油吧!
三、 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

四、 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

五、資源消耗對比

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 — 程序使用的虛擬記憶體總量,單位kb。VIRT=SWAP+RES
RES — 程序使用的、未被換出的實體記憶體大小,單位kb。RES=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壓力高。

比較結果:

在這裡插入圖片描述
雖然jmeter提供UI介面,但是其壓測指令碼也依賴UI介面,導致其無法在Linux伺服器上直接編輯寫指令碼,只有編寫好指令碼後再傳到Linux伺服器。
關於對於壓測工具的選擇

如果你想做場景的壓測,而不是單個介面的壓測
可使用jmeter或locust,支援介面串聯,介面body引數化,思考時間等複雜場景
如果你壓測要求的併發比較高,需要使用分散式壓測
可使用jmeter或locust
如果你關注介面的返回,多維度壓測報告統計
jmeter,jmeter,jmeter
如果想盡快編寫介面,只關注介面的傳送,造成的QPS和錯誤率
可使用wrk或ab
實踐中也可以選擇自己熟悉的壓測工具

由於單臺4核8G伺服器對待測介面最高能造成2萬的QPS,還是距離我需要的6萬還有一定距離,這時候可以使用Jmeter的分散式壓測

當然還有更多我還沒了解到的優秀壓測工具,壓測結果存在一定侷限,僅供參考