一個簡易的負載測試開發紀錄,enjoy it!
一、負載測試簡介
我們剛實作完一個新的軟體服務,心中常常會有一些的疑問:
- 這個服務能承受多大的流量?
- 整個服務的 bottleneck 在哪?
- bottleneck 是 CPU-bound、I/O-bound、還是網路 bandwidth 不夠?
因此,系統開發完成到上線之間,通常需要對整體服務和服務中的各個模組做負載測試[註1],以確保服務品質。那麼,一個服務的負載能力如何定義呢?一般 HTTP 服務我們可以估計 RPS (Request Per Second) 這個指標。例如:
假設每日 20 萬流量的服務,粗估一下,除以 1 天秒數 86400 再乘以尖峰值可能的倍數 (如 5 倍),得到大約 12 RPS,而服務能吃下 2 倍的流量會更好更穩定,因此可以把目標設在 24 RPS 左右[註2]。
有了這個 RPS 數值,再來就是要使用專業的工具來模擬這些請求;市面上這種壓力測試的工具很多,像是 ab、vegeta、wrk 等等,這些工具各有利弊,一般來說有這些差異:
- 有沒有 multi-thread 可以更大量的發送請求?
- 支援的協定有哪些? (HTTP/1.1 or HTTP/1.0, keep-alive or not)
- 有沒有支援分散式發送請求?
在這裡,我選擇用 Vegeta,Vegeta 是一個用 Go 語言實作的多功能的 HTTP 壓力測試工具,下面就簡單介紹一下 vegeta 的使用吧!
[註1] 細分有效能測試 (Performance testing)、負載測試 (Load testing) 和壓力測試 (Stress testing) 3 個種類,在這裡不嚴格區分。
[註2] 如果有複雜 DB 請求,可能會先遇到 10 RPS 這個效能瓶頸。
二、Vegeta 測試工具指令
照著官方介紹便能完成初步安裝和使用:
github - tsenart / Vegeta
https://github.com/tsenart/vegeta
1. 簡單的 GET 測試
Command:
$ echo "GET http://httpbin.org/get" | vegeta attack -rate=10/s -duration=10s | vegeta report
Response:
Requests [total, rate] 100, 10.10 Duration [total, attack, wait] 10.254757441s, 9.901062s, 353.695441ms Latencies [mean, 50, 95, 99, max] 325.419845ms, 265.070463ms, 743.105204ms, 1.232783384s, 1.477413856s Bytes In [total, mean] 21900, 219.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 100.00% Status Codes [code:count] 200:100 Error Set:
[用心去感覺] curl 工具
只是要打打看 API 通不通用的話,不要殺雞用牛刀,用 curl 工具就好,例如:
Command:
$ curl -X GET http://httpbin.org/get
Response:
{ "args": {}, "headers": { "Accept": "*/*", "Host": "httpbin.org", "User-Agent": "curl/7.54.0" }, "origin": "60.245.65.135, 60.245.65.135", "url": "https://httpbin.org/get" }
2. multipart/form-data POST 測試
步驟多一點的 multipart/form-data POST 測試,例如,想送一個帶檔案的 multipart/form-data POST:
$ curl -s -X POST -F audio=@mysound.wav 'http://localhost/sound'
a. Vegeta commands for sending requests
Vegeta command:
$ vegeta attack -name=10qps_20s -rate=10/s -duration=20s -targets=targets.txt > results.bin
in targets.txt:
POST http://localhost/sound Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1233211234567 @body.txt
in body.txt:
------WebKitFormBoundary1233211234567 Content-Disposition: form-data; name="audio"; filename="mysound.wav" Content-Type: audio/wav /..binary content../ ------WebKitFormBoundary1233211234567--
Report generating command:
$ vegeta report results.bin $ vegeta report -type='hist[0,1s,2s,4s,8s,16s,32s,64s]' results.bin $ cat results.bin | vegeta plot > plot.html
b. Vegeta report
Overview:
Requests [total, rate] 200, 10.05 Duration [total, attack, wait] ******s, ******s, ******s Latencies [mean, 50, 95, 99, max] ******s, ******s, ******s, ******s, ******s Bytes In [total, mean] 22032, 110.16 Bytes Out [total, mean] 474739380, 2373696.90 Success [ratio] 81.00% Status Codes [code:count] 0:38 200:162 Error Set: Post http://localhost/sound: net/http: timeout awaiting response headers
Histogram report:
Bucket # % Histogram [0s, 1s] 41 20.50% ############### [1s, 2s] 4 2.00% # [2s, 4s] 8 4.00% ### ... [32s, 1m4s] 0 0.00% [1m4s, +Inf] 0 0.00%
Plot:
[用心去感覺] 製作 POST 的小細節
- multipart/form-data POST 的 MIME type 查詢 [link]
- 注意 POST body 中的分隔線數量!
- 一般分隔: --[boundary]
- 最後分隔: --[boundary]--
- Body 實際內容前要空一格
當然 vegeta 不只這些功能,還有 realtime 監測或當 library 等等華麗的的功能,這些就要一邊使用一邊慢慢探索囉。
References
github - vegeta
https://github.com/tsenart/vegeta
github - wrk
https://github.com/wg/wrk
wiki - HTTP 持久連接
https://zh.wikipedia.org/wiki/HTTP%E6%8C%81%E4%B9%85%E8%BF%9E%E6%8E%A5
vegeta - multipart/form-data with uploading CSV file
https://github.com/tsenart/vegeta/issues/347
Do you need to run load tests? Vegeta to the rescue!
https://medium.com/@carlosaugustosouzalima/do-you-need-to-run-load-tests-vegeta-to-the-rescue-7e8818127a65
火丁筆記 - 說說壓力測試工具
https://huoding.com/2017/05/31/620
沒有留言:
張貼留言