ããã¯ããªã«ãããããŠæžãããã®ïŒ
Vegetaãšãããå²ãšåæ§çãªè² è·ãã¹ãããŒã«ããããã³ãã³ãã©ã€ã³ã§ç°¡åã«äœ¿ããããªã®ã§è©ŠããŠã¿ããããšããããšã§ã
GitHub - tsenart/vegeta: HTTP load testing tool and library. It's over 9000!
Apache Benchã®ä»£ããã«äœ¿ãããã©ãã§ãããïŒãããã®æèŠã§ãèŠãŠã¿ãŸããã
Vegeta
Vegetaãšããã®ã¯ãHTTPã®è² è·ãã¹ãããŒã«ã§ãã
Vegeta is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate.
GitHub - tsenart/vegeta: HTTP load testing tool and library. It's over 9000!
ååããŸãããâŠã§ããããªããžããªã«èŒããããŠããç»åããã®ãŸããŸã§ããã
Goèšèªã§äœæãããŠãããCLIãšããŠã䜿ããŸãããã©ã€ãã©ãªãšããŠãå©çšããããšãã§ããŸãã
It can be used both as a command line utility and a library.
ã¬ããŒãã¯ãããã¹ããJSONããã¹ãã°ã©ã ãã°ã©ãã§èŠãããããããã§ãã
ãã¹ã察象ã¯ãããã©ã«ãã¯æšæºå
¥åã§äžããããã§ããããã¡ã€ã«ã§çšæããŠè€æ°ã®ã¿ãŒã²ããã«å¯ŸããŠè² è·ããããããšã
ã§ããããã§ãã
忣å®è¡ã¯çŽæ¥ã¯ãµããŒãããŠããªãããã§ãããSSHã䜿ã£ãŠè€æ°ã®ãµãŒããŒã§Vegetaãå®è¡ããçµæã®ã¬ããŒãã
çµ±åããããšã§åæ£å®è¡ãå®çŸããããã§ãã
éäžçµéããªã¢ã«ã¿ã€ã ã«èŠãããã«ã¯ãä»ã®ããŒã«ã®å©ããå¿ èŠãªæš¡æ§ã
ãšãŸããå眮ãã¯ãããããã«ããŠãå®éã«äœ¿ã£ãŠã¿ãŸãããã
ç°å¢
ç°å¢ã¯ãUbuntu Linux 18.04 LTSã§è¡ããŸããã
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic
ã€ã³ã¹ããŒã«
CLIãšããŠã¯ããã€ããªãããŠã³ããŒãããŠããŠå±éããã°äœ¿ãããšãã§ããŸãã
$ wget https://github.com/tsenart/vegeta/releases/download/cli%2Fv12.3.0/vegeta-12.3.0-linux-amd64.tar.gz $ tar xf vegeta-12.3.0-linux-amd64.tar.gz
ããŒãžã§ã³ã12.3.0âŠã
$ ./vegeta -version Version: 12.3.0 Commit: 7bf09f4fab4d852141935796455c17459d212098 Runtime: go1.12 linux/amd64 Date: 2019-04-14T13:29:49Z"
äœ¿ãæ¹ã¯ããã«ããèŠããšããã§ãããã
$ ./vegeta -h
æåŸã®æ¹ã«ãã³ãã³ãã®å®è¡äŸãåºåãããŸãã
echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta report vegeta report -type=json results.bin > metrics.json cat results.bin | vegeta plot > plot.html cat results.bin | vegeta report -type="hist[0,100ms,200ms,300ms]"
ããšã¯ãããã¥ã¢ã«ãèŠãªãããªãã·ã§ã³ã®æå³ã確èªãã€ã€âŠã§ããã
ãã¹ã察象ãµãŒããŒ
Vegetaã¯è² è·ãã¹ãããŒã«ãªã®ã§ãè² è·ãããã察象ãããªããšå§ãŸããŸããã
ããã¯ãç°¡åã«Node.jsïŒExpressã§çšæããŸããã
$ node -v v10.15.3 $ npm init $ npm i express
å©çšããExpressã®ããŒãžã§ã³ã¯ããã¡ãã
"dependencies": { "express": "^4.16.4" },
äœæããã¢ããªã±ãŒã·ã§ã³ã3ã€ããšã³ããã€ã³ããäœæããŸããã
â»GETãPOSTã®ãã¹ã«åé·æãããŸãããä»åã¯æç¢ºã«ãã¹ãåããŸãã
server.js
const express = require('express'); const app = express(); const bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.get('/', (req, res) => res.send('Hello!!')); app.get('/echo/get', (req, res) => res.send(req.query.message)); app.post('/echo/post', (req, res) => res.send(req.body.message)); app.listen(3000, () => console.log(`[${new Date()}] Server startup`));
package.jsonã®scriptsã«ç»é²ããŠ
"scripts": { "start": "node server.js", "test": "echo \"Error: no test specified\" && exit 1" },
èµ·åã
$ npm start > target-server@1.0.0 start /path/to/target-server > node server.js [Sun Apr 28 2019 21:05:04 GMT+0900 (GMT+09:00)] Server startup
確èªã
$ curl localhost:3000 Hello!! $ curl localhost:3000/echo/get?message=hello hello $ curl -XPOST -H 'Content-Type: application/x-www-form-urlencoded' localhost:3000/echo/post -d 'message=hello' hello
ããã§ãæºåå®äºã§ãã
åäžã®URLã«å¯ŸããŠè² è·ããããŠã¿ã
ããã§ã¯ãVegetaã䜿ã£ãŠå¯Ÿè±¡ã®ãµãŒããŒã«è² è·ããããŠã¿ãŸãããã
以äžã®ã³ãã³ãã§ããhttp://localhost:3000ãã«HTTP GETã§ã5ç§éè² è·ããããŠçµæã衚瀺ããŸããã¬ããŒãã¯ããã©ã«ãã§
æšæºåºåã«åºåãããã®ã§ããããããã«ãvegeta reportãã§æŽåœ¢ããŸãã
$ echo 'GET http://localhost:3000' | ./vegeta attack -duration=5s | ./vegeta report
çµæã
Requests [total, rate] 250, 50.20 Duration [total, attack, wait] 4.981730015s, 4.980160389s, 1.569626ms Latencies [mean, 50, 95, 99, max] 1.096255ms, 1.092932ms, 1.595155ms, 2.017918ms, 3.177145ms Bytes In [total, mean] 1750, 7.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 100.00% Status Codes [code:count] 200:250 Error Set:
çµæã®èªã¿æ¹ã¯ãã¬ããŒãã®ãã©ãŒãããããtextãã®ãšããã«æžããŠãããŸãã
- Requests
- total âŠ å šå®è¡åæ°
- rate ⊠ç§éã®å®è¡åæ°
- Duration
- total âŠ è² è·ããããã®ã«èŠããæéïŒattackïŒwaitïŒ
- attack âŠ å šãªã¯ãšã¹ããå®è¡ããã®ã«èŠããæéïŒtotal - waitïŒ
- wait ⊠ã¬ã¹ãã³ã¹ãåŸ ã£ãŠããæé
- Latencies ⊠ãããããå¹³åã50ïŒ ã95ïŒ ã99ïŒ ããŒã»ã³ã¿ã€ã«ãæå€§å€
- Bytes InïŒBytes Out ⊠ãªã¯ãšã¹ãïŒã¬ã¹ãã³ã¹ã®éåä¿¡ã®ãã€ãæ°
- Success ⊠ãªã¯ãšã¹ãã®æåçïŒãªãã200ãš400ããšã©ãŒãšããŠã«ãŠã³ããããªãïŒ
- Status Codes ⊠ã¹ããŒã¿ã¹ã³ãŒãã®ãã¹ãã°ã©ã ïŒ0ã¯ã倱æïŒ
- Error Set ⊠倱æãããªã¯ãšã¹ããšãã®å 容
æåã®äŸããç§é50ãªã¯ãšã¹ããšãªããªãæ¿ããã®ã§ãã¡ãã£ãšäžããŠã¿ãŸããããã-rateãã§æå®ããããšãã§ããŸãã
ç§ãããã3ã«ããŠã¿ãŸãããã
$ echo 'GET http://localhost:3000' | ./vegeta attack -duration=5s -rate=3 | ./vegeta report Requests [total, rate] 15, 3.21 Duration [total, attack, wait] 4.668077623s, 4.666875044s, 1.202579ms Latencies [mean, 50, 95, 99, max] 1.061737ms, 935.134µs, 2.220665ms, 2.486884ms, 2.486884ms Bytes In [total, mean] 105, 7.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 100.00% Status Codes [code:count] 200:15 Error Set:
ãšã©ãŒã®å ŽåãèŠãŠã¿ãŸãããã詊ãã«ãNot Foundã«ãªãURLã§è©ŠããŠã¿ãŸãã
$ echo 'GET http://localhost:3000/notfound' | ./vegeta attack -duration=5s -rate=3 | ./vegeta report Requests [total, rate] 15, 3.21 Duration [total, attack, wait] 4.667400657s, 4.666715559s, 685.098µs Latencies [mean, 50, 95, 99, max] 1.38848ms, 963.456µs, 4.354423ms, 4.627119ms, 4.627119ms Bytes In [total, mean] 2205, 147.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 0.00% Status Codes [code:count] 404:15 Error Set: 404 Not Found
次ã¯ãPOSTããŠã¿ãŸãããã
HTTPããã£ã®å
容ã¯ã以äžã®ãããªããã¹ããã¡ã€ã«ãçšæã
body.txt
message=test
URLã®åã«ãä»åºŠã¯ãPOSTããæå®ããŠè² è·ãæžããŸããäœæããHTTPããã£çšã®ããã¹ããã¡ã€ã«ã¯ãã-bodyããªãã·ã§ã³ã§
æå®ããŸããããšãã-headerãã§HTTPããããŒã远å ããŸããã
$ echo 'POST http://localhost:3000/echo/post' | ./vegeta attack -duration=5s -body=body.txt -header='Content-Type: application/x-www-form-urlencoded' | ./vegeta report
çµæã
Requests [total, rate] 250, 50.20 Duration [total, attack, wait] 4.981419329s, 4.980088019s, 1.33131ms Latencies [mean, 50, 95, 99, max] 1.399184ms, 1.358172ms, 1.962928ms, 3.146063ms, 5.236047ms Bytes In [total, mean] 1250, 5.00 Bytes Out [total, mean] 3250, 13.00 Success [ratio] 100.00% Status Codes [code:count] 200:250 Error Set:
ã-bodyããªãã·ã§ã³ã¯ãããŸã§ãã¡ã€ã«ãæå®ããã®ã§ããã¡ã€ã«ãçšæããã®ã¯é¢åãšæããããããŸããã
ããããæã¯ãJSONãã©ãŒãããã䜿ããšãããããããŸããããããããšãHTTPããã£ãããããŒã®å 容ã
$ jq -ncM '{method: "POST", url: "http://localhost:3000/echo/post", body: "message=test" | @base64, header: {"Content-Type": ["application/x-www-form-urlencoded"]}}' | ./vegeta attack -format=json -duration=5s | ./vegeta report
çµæã
Requests [total, rate] 250, 50.20 Duration [total, attack, wait] 4.981231371s, 4.980126573s, 1.104798ms Latencies [mean, 50, 95, 99, max] 1.328564ms, 1.192952ms, 1.933122ms, 2.922471ms, 23.264626ms Bytes In [total, mean] 1000, 4.00 Bytes Out [total, mean] 3000, 12.00 Success [ratio] 100.00% Status Codes [code:count] 200:250 Error Set:
çµæãã°ã©ãã§èŠã
ãããŸã§ããã¹ã圢åŒã§çµæãèŠãŠããŸãããããvegeta plotãã䜿ãããšã§ã°ã©ã圢åŒã§ãèŠãããšãã§ããŸãã
$ echo 'GET http://localhost:3000' | ./vegeta attack -duration=5s | ./vegeta plot > report.html
çµæã®HTMLã衚瀺ãããšããããªæãã«ãªããŸãã

ãã®äŸã§ã¯5ç§éè² è·ããããŠããŸããããã®æšç§»ãã°ã©ã衚瀺ããæãã§ããã
Requests [total, rate] 250, 50.20 Duration [total, attack, wait] 4.981240384s, 4.980150818s, 1.089566ms Latencies [mean, 50, 95, 99, max] 942.97µs, 880.2µs, 1.525036ms, 2.03296ms, 2.314226ms Bytes In [total, mean] 1750, 7.00 Bytes Out [total, mean] 0, 0.00 Success [ratio] 100.00% Status Codes [code:count] 200:250 Error Set:
è€æ°ã®URLãžè² è·ãããã
è€æ°ã®URLã«å¯ŸããŠè² è·ããããå Žåã¯ã以äžã®ãã©ãŒãããã«åŸã£ãŠå¯Ÿè±¡ã®URLãåæããŸãã
test-scenario.txt
GET http://localhost:3000 GET http://localhost:3000/echo/get?message=test POST http://localhost:3000/echo/post Content-Type: application/x-www-form-urlencoded @body.txt
HTTPããããæå®ããããšãã§ããHTTPããã£ã¯ãã¡ã€ã«ã§æå®ããŸãã
ãã®ãã¡ã€ã«ããã-targetsããªãã·ã§ã³ã§æå®ããŸãã
$ ./vegeta attack -targets=test-scenario.txt -duration=5s | ./vegeta report
çµæã
Requests [total, rate] 250, 50.20 Duration [total, attack, wait] 4.980628214s, 4.980055554s, 572.66µs Latencies [mean, 50, 95, 99, max] 1.208511ms, 1.067828ms, 1.793813ms, 2.42757ms, 16.116178ms Bytes In [total, mean] 1335, 5.34 Bytes Out [total, mean] 1079, 4.32 Success [ratio] 100.00% Status Codes [code:count] 200:250 Error Set:
âŠåå¥ã®URLã«å¯Ÿããçµæã¯ããããªãæãïŒ
çµæãã°ã©ãã«ããŠã¿ãŸãããã
$ ./vegeta attack -targets=test-scenario.txt -duration=5s | ./vegeta plot > report.html
ãã¡ãã§ããããããªãããã§âŠã

ãŸãããããŸããªäœ¿ãæ¹ã¯ããã£ãã®ã§ãè¯ããšããŸãããã
ããã¡ãã£ãšåãããå Žåã¯ãApache JMeterãLocustã䜿ãã®ãè¯ãã®ã§ããããã