🍋

vegetaによる負荷試験のメモ

2024/03/24に公開

vegetaはgolang製の負荷試験ツールです。goなのでバイナリ一つおくだけで実行でき、利用がとても楽ちんです。

https://github.com/tsenart/vegeta

本記事はvegetaの使い方は記載していません。
シンプルな実行例と、Cookieの指定方法、POSTの利用方法についてメモとして記載しています。

シンプルな実行例

秒間15req, 600秒間, 単一URLで負荷をかける

$ echo -e "GET https://target.foo.bar.local/ | ./vegeta attack -rate=15 -duration=600s -insecure -keepalive connections 10 >> vegeta.log

秒間30req, 1200秒間, 複数のURLで負荷をかける、あとBasic認証もしたい時

$ echo -e "GET https://username:password@target.foo.bar.local/\nGET https://user001aa@target.foo.bar.local/detail/1" | ./vegeta attack -rate=30 -duration=1200s -insecure -keepalive connections 10 >> vegeta.log

Cookieの指定

Webアプリに認証が必要な場合、あらかじめブラウザで認証しておいてCookieをセットしてあげるのが楽です。

適当なファイルを作成し、以下のようにアクセスURLに引き続いてCookieを記載することで、指定したCookieをセットした状態で負荷試験ができます。
(Cookieというか、HTTPヘッダの指定ですね。)

$ cat targetfile
GET http://target.foo.bar.local/
Cookie: type=user; session_id=abcdefghijklmn12345;

実行

$ bin/vegeta attack -rate=1 -duration=1s -targets=targetfile -timeout=10s | tee result.bin

結果

$ bin/vegeta report result.bin
Requests      [total, rate, throughput]         1, 1.00, 1.00
Duration      [total, attack, wait]             155.382ms, 0s, 155.382ms
Latencies     [min, mean, 50, 90, 95, 99, max]  155.382ms, 155.382ms, 155.382ms, 155.382ms, 155.382ms, 155.382ms, 155.382ms
Bytes In      [total, mean]                     26322, 26322.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:1
Error Set:

複数URLの場合、Cookieもそれだけ書く必要がありました。

$ cat targetfile
GET http://target.foo.bar.local/
Cookie: type=user; session_id=abcdefghijklmn12345;

GET http://target.foo.bar.local/some_uri/
Cookie: type=user; session_id=abcdefghijklmn12345;

このファイルで実行した場合、

$ bin/vegeta attack -rate=1 -duration=5s -targets=targetfile -timeout=10s | tee result.bin

2つのURLを指定していますが、一度にアクセスされるのは1URLでした。
よって、上記のvegeta実行では /と/some_uri が1秒ごとに交互に実行されています。

$ bin/vegeta report result.bin
Requests      [total, rate, throughput]         5, 1.30, 1.23
Duration      [total, attack, wait]             4.053s, 3.848s, 204.961ms
Latencies     [min, mean, 50, 90, 95, 99, max]  204.961ms, 445.431ms, 520.305ms, 731.258ms, 731.258ms, 731.258ms, 731.258ms
Bytes In      [total, mean]                     148442, 29688.40
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:5
Error Set:

これは-rateが1のためです。
-rateを2にすると、
毎秒、/ と /some_uri が同時にアクセスされます。

5秒間実行しているので合計リクエスト数は10となります。
同時に2接続、2req投げて、1秒後(正確には応答待ち時間を引くはず)に再度2reqを繰り返していると思われます。

$ bin/vegeta report result.bin
Requests      [total, rate, throughput]         10, 2.22, 1.98
Duration      [total, attack, wait]             5.049s, 4.5s, 549.036ms
Latencies     [min, mean, 50, 90, 95, 99, max]  123.354ms, 573.984ms, 588.299ms, 1.126s, 1.321s, 1.321s, 1.321s
Bytes In      [total, mean]                     305300, 30530.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:10
Error Set:

なお、

  -keepalive
    	Use persistent connections (default true)
  -connections int
    	Max open idle connections per target host (default 10000)

のとおりkeepaliveはデフォルトtrueとなっています。
なので、先ほどのrate=2では2つの接続がkeepaliveされて5秒間リクエストが投げられます。
それぞれ異なるPCからリクエストされることを想定して
-keepalive=falseにしてみました。

$ bin/vegeta attack -rate=2 -duration=5s -targets=targetfile -timeout=10s -keepalive=false > result.bin

なぜかkeepalive offのほうがLatenciesが小さくなっていますが、試行数が少ないので増やせば差が出るかもしれません。(今回はそこまでは調べてないです)

$ bin/vegeta report result.bin
Requests      [total, rate, throughput]         10, 2.22, 1.96
Duration      [total, attack, wait]             5.109s, 4.5s, 609.516ms
Latencies     [min, mean, 50, 90, 95, 99, max]  97.161ms, 390.925ms, 413.631ms, 648.178ms, 686.84ms, 686.84ms, 686.84ms
Bytes In      [total, mean]                     305300, 30530.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:10
Error Set:

POSTしたい時

POSTの場合こういうファイルを用意して、targetfile内で@でパス指定する(もしくはvegetaに-bodyオプションでファイルパスを渡す)

$ cat postdata.txt
paramname=testdata
$ cat targetfile
GET http://target.foo.bar.local/
Cookie: type=user; session_id=abcdefghijklmn12345;

GET http://target.foo.bar.local/some_uri/
Cookie: type=user; session_id=abcdefghijklmn12345;

POST http://target.foo.bar.local/post_uri/
@/path/to/postdata.txt
Cookie: type=user; session_id=abcdefghijklmn12345;

実行方法はGETだけの時と同じですね。

$ bin/vegeta attack -rate=2 -duration=5s -targets=targetfile -timeout=10s > result.bin

Discussion