[技術博客]幾種網站壓力測試工具調研與使用
我們在beta階段對於網站訪問做了不少優化工作,因此打算在本階段尾聲時對網站做了一個簡單的壓力測試,進而估算一下網站現在的並發量及處理能力。因此,我們對現有較流行的幾種網絡壓力測試工具進行了簡單調研並嘗試部署使用。
1. 在線網站
有一些網站提供了在線壓力測試功能,例如騰訊提供的 wetest 壓測大師, Nice tool, load impact, Post Json, PostMan等。我們也嘗試使用了其中的一些,就使用上來說比較簡單,但是在一些特殊極端情況下不是十分理想。
1.1. 優勢
經過我們的嘗試,我們認為在線網站主要有以下優勢
-
配置簡單 使用在線網站不需要自己在本地搭載環境,編寫代碼,並有一個較完善的UI界面。
-
功能多 以wetest為例,可以提供監控核心性能指標如TPS、響應時間CPU、內存、磁盤IO、網卡負載、壓力機性能監測等(需求騰訊雲)
-
結果展示直觀 上述大部分網站都可以直接以圖表的形式顯示結果,直觀並且可以直接在展示中使用
1.2. 缺陷
-
並發限制 在線網站往往有最大並發限制,例如上述網站未登錄的情況下都限制最大並發10~50。wetest,nicetool可以通過注冊的方式增加並發限制,然而注冊過程較繁瑣,需要提供證明材料。
-
可定制化較低 很容易理解,在線網站測試的可定制化程度一定比自己寫代碼要低。
-
鏈接速度問題 在做實際測試是,我們當然希望測試的是服務器的性能而不是網絡質量。因此,使用網站的結果可能會沒有直接在服務器上部署測試來的准確。
1.3. 測試結果樣例
這里我們以nicetool為例,執行50並發,100請求的測試,結果如下:
Summary:
Total: 1.3244 secs
Slowest: 0.4565 secs
Fastest: 0.1701 secs
Average: 0.2889 secs
Requests/sec: 151.0075
Response time histogram:
0.170 [1] |
0.199 [88] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.227 [3] |■
0.256 [1] |
0.285 [0] |
0.313 [0] |
0.342 [36] |■■■■■■■■■■■■■■■■
0.371 [21] |■■■■■■■■■■
0.399 [0] |
0.428 [14] |■■■■■■
0.456 [36] |■■■■■■■■■■■■■■■■
Latency distribution:
10% in 0.1722 secs
25% in 0.1751 secs
50% in 0.3367 secs
75% in 0.4204 secs
90% in 0.4365 secs
95% in 0.4415 secs
99% in 0.4536 secs
Details (average, fastest, slowest):
DNS+dialup: 0.0196 secs, 0.1701 secs, 0.4565 secs
DNS-lookup: 0.0031 secs, 0.0000 secs, 0.0131 secs
req write: 0.0001 secs, 0.0000 secs, 0.0027 secs
resp wait: 0.2689 secs, 0.1699 secs, 0.3761 secs
resp read: 0.0003 secs, 0.0001 secs, 0.0049 secs
Status code distribution:
[200] 200 responses
2. 測試工具
除了在線網站,我們也調研並使用了一些其它工具,包括 ab, pylot, siege等。下面做一下簡單介紹,基本按照推薦順序。
2.1. ab
ab 的全稱是apache bench,是由Apache提供的一款簡單高效的測試工具,支持windows和linux等。
2.1.1. 使用方法
首先需要下載Apache,對於windows,cmd進入安裝目錄的BIN文件夾下就可以執行ab了。對於Linux,一般可以通過安裝Apache服務解決。
ab包括以下參數:
-n 執行的請求數量
-c 並發請求個數
-t 測試所進行的最大秒數
-p 包含了需要POST的數據的文件
-T POST數據所使用的Content-type頭信息
-k 啟用HTTP KeepAlive功能,即在一個HTTP會話中執行多個請求,默認時,不啟用KeepAlive功能
一個簡單的例子是
ab -n 100 -c 100 http://www.baidu.com/
2.1.2. 測試結果
我們使用
ab -n 100 -c 100 https://ratemycourse.tk/
進行了測試,測試結果如下:
Server Software: cloudflare
Server Hostname: ratemycourse.tk
Server Port: 443
SSL/TLS Protocol: TLSv1.2,ECDHE-ECDSA-CHACHA20-POLY1305,256,256
TLS Server Name: ratemycourse.tk
Document Path: /
Document Length: 6856 bytes
Concurrency Level: 100
Time taken for tests: 3.153 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 732100 bytes
HTML transferred: 685600 bytes
Requests per second: 31.72 [#/sec] (mean)
Time per request: 3153.013 [ms] (mean)
Time per request: 31.530 [ms] (mean, across all concurrent requests)
Transfer rate: 226.75 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 489 632 130.8 611 1232
Processing: 167 412 359.8 347 2159
Waiting: 164 223 86.2 193 817
Total: 695 1044 405.5 927 3133
Percentage of the requests served within a certain time (ms)
50% 927
66% 1029
75% 1078
80% 1154
90% 1586
95% 1895
98% 2818
99% 3133
100% 3133 (longest request)
2.1.3. 優勢與缺陷
ab提供的測試結果內容較多,十分完整,包括連接成功數,響應時間等多種內容並做了簡單分析,足夠使用。主要缺點是不能監控,沒有圖形化結果。ab好像是單核的,因此高並發時可能造成測試瓶頸。另外我服務器上已經使用了Nginx作為webserver,再安裝Apache等還需要處理一些沖突問題。
2.2. siege
siege 是一個十分常用的開源的web服務壓力測試工具,可以模擬數千並發的請求,並給出一個簡單的統計。siege的安裝使用非常簡單,下以Ubuntu/Debian為例。
2.2.1. 安裝siege
siege可以通過編譯源碼與apt兩種方式安裝,需要注意的是官網鏈接不是很穩定,雖然壓縮包大小僅有511K但是依然需要代理訪問,因此更推薦使用apt安裝。
源碼安裝的方式如下:
wget http://download.joedog.org/siege/siege-latest.tar.gz
tar -zxvf siege-latest.tar.gz
cd siege-4.0.4/
./configure
make
make install
sudo apt install siege
2.2.2. siege簡單教程
我們摘錄了這篇文章中介紹用法的部分。
-C,或–config 在屏幕上打印顯示出當前的配置,配置是包括在他的配置文件$HOME/.siegerc中,可以編輯里面的參數,這樣每次siege 都會按照它運行.
-v 運行時能看到詳細的運行信息
-c n,或–concurrent=n 指定並發的用戶個數,-c 200指定並發數200。模擬有n個用戶在同時訪問,n不要設得太大,因為越大,siege 消耗本地機器的資源越多
-i,–internet 隨機訪問urls.txt中的url列表項,以此模擬真實的訪問情況(隨機性),當urls.txt存在是有效。默認為urls.txt列表從上到下來壓。
-d n,–delay=n hit每個url之間的延遲,在0-n之間
-r n,–reps=n 重復運行測試n次,不能與-t同時存在
-t n,–time=n 持續時間。即測試持續時間。默認是分鍾。例: -t10S,(10秒) -t5M,(5分鍾) -t1H,(1小時)
-l 運行結束,將統計數據保存到日志文件中siege .log,一般位於/usr/local/var/siege .log中,也可在.siegerc中自定義
-R SIEGERC,–rc=SIEGERC 指定用特定的siege 配置文件來運行,默認的為$HOME/.siegerc
-f FILE, –file=FILE 指定用特定的urls文件運行siege ,默認為urls.txt,位於siege 安裝目錄下的etc/urls.txt
-u URL,–url=URL 測試指定的一個URL,對它進行”siege “,此選項會忽略有關urls文件的設定
-b 進行壓力測試,不進行延時。
-A, --user-agent=“text” 設置請求的User-Agent
使用以上命令基本可以滿足大部分測試需求了。以我們的測試為例,我們考察了1000並發下的網站工作情況,使用了如下命令:
siege -c 100 https://ratemycourse.tk -i -b
2.2.3. 測試結果
簡單測試結果如下:
Lifting the server siege...
Transactions: 100 hits
Availability: 100.00 %
Elapsed time: 2.30 secs
Data transferred: 0.23 MB
Response time: 1.29 secs
Transaction rate: 45.65 trans/sec
Throughput: 0.10 MB/sec
Concurrency: 58.68
Successful transactions: 100
Failed transactions: 0
Longest transaction: 1.53
Shortest transaction: 1.04
2.2.4. 優勢與缺點
siege安裝方便,比起ab,不需要解決與nginx可能的沖突的問題。siege的測試速度直觀上比ab更快。siege提供的信息要略少一些,不過對於簡單分析依然足夠。
另外siege有一個小坑:siege的最大並發鏈接默認值是255,需要手動到配置文件中修改。siege在WSL和部分macOS上啟動會失敗,建議使用虛擬機或完整的Linux環境。
2.3. pylot
pylot是一個python寫的測試工具,支持命令行與圖形界面,支持生成圖表,配置簡單易用。其實pylot是我最早嘗試的工具,因為簡介博客說它基於python,又可以畫圖。
然而簡介總是美好的,現實總是殘酷的。簡單來說,就目前請不要再試圖使用或推薦pylot了。
首先是官網進不去。我們在博客的介紹里找到了所謂的官網:www.pylot.org,然而實際上這個網站現在是emmm,在線發牌。
幸運的是,我們還有web archive這個老朋友。emmm,然而看上去最后更新的版本2009/07/06的。另外它好像只支持python2,我也不知道有沒有人在繼續維護。
就結論來說,我好像浪費了一小時試圖搞定這個玩意。
2.4. 簡單總結
總的來說,這些測試工具比起網站可以自己部署,可以自己定制功能。直接部署到服務器上或者與服務器有較高連接速率的服務器上(例如同一局域網)可以最大限度避免網絡質量導致的誤差。相較於在線測試網站,我們也可以自定義更大的連接數,測試更高的並發。
3. 造輪子自己寫腳本
除了使用上面的工具之外,我們還可以使用自己寫的一些其他腳本實現更多功能。利用python的request庫,簡單的就可以模擬一個請求。自己寫的腳本往往可以實現更多特殊的功能,但是他們同樣也會面臨一些問題,例如魯棒性,異常處理完整性,測試的公平准確性等問題。例如,下面的測試代碼模擬了連續25秒,每秒請求200次的壓力測試。
import requests
import threading
import time
class thread1(threading.Thread):
count200=0
count502=0
count504=0
count500=0
countelse=0
def __init__(self, threadID, name):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
def run(self):
time.sleep(50)
code = requests.get(YOUR_WEB_SITE).status_code
if int(code)==200:
thread1.count200+=1
elif int(code)==502:
thread1.count502+=1
elif int(code)==504:
thread1.count504+=1
elif int(code)==500:
thread1.count500+=1
else:
thread1.countelse+=1
if __name__=="__main__":
threads=[]
for i in range(5000):
thread=thread1(i, "Thread-{}".format(i))
threads.append(thread)
for i in threads:
i.start()
time.sleep(0.005)
for i in threads:
i.join()
print(thread1.count200,thread1.count502,thread1.count504,thread1.count500,thread1.countelse)
4. 最終推薦
在我們實際使用中,我們使用了siege輔以自己編寫的腳本進行了測試,網站壓力測試結果可以參考我們的后續博客。實際上,我們認為ab和siege都是十分優秀的解決方案。