vegeta は、Go で書かれた HTTP 負荷テストツールであり、コマンドラインインタラクティブに使用され、結果の分析として集計およびグラフを生成することができます。
HTTP load testing tool and library. It's over 9000!
基本的な使用方法#
詳細な使用方法については、README の内容を参照してください。2 つの方法で使用することができます:コマンドラインインタラクティブおよび Go プログラムにライブラリとして組み込む方法です。私は brew を使用して vegeta をインストールしましたが、テストプロセス全体はテストを実行するために Go でスクリプトを作成することで行われました。詳細については、コードスニペットを参照してください。
ライブラリの形式ではなく、exec.Command()
関数を使用してコマンドラインを実行しました。
使用された具体的な vegeta コマンド
- attack: API を呼び出すコマンドで、rate は 1 秒あたりの呼び出し回数を表し、duration は呼び出す秒数を表します。body は POST リクエストのリクエストボディを指し、name はこのテストに名前を付けるためのものです(省略可能)、tee は bin 形式の生データファイルを生成し、report はレポートを生成し、ここではコマンドラインに出力します。
echo "POST http://172.17.1.36:30898/hello" | vegeta attack -rate=2000 -duration=1s -body=query.json -timeout=0 -name=hello | tee ./result/results-null.bin | vegeta report
- レポートファイルの生成、ここでは bin 生データファイルから txt ファイルを生成します。
vegeta report -type=text results-query.bin > repost.txt
- 分析グラフの生成、plot を使用するとインタラクティブなグラフが生成されますが、複数の結果を 1 つのグラフにマージする場合は、最初のコマンドで必ず - name パラメータを使用して名前を付ける必要があります。
vegeta plot results-null.bin results-sleep.bin results-query.bin > plot-all.html
テストシナリオ#
Java と Go で 2 つの REST サービスを作成し、それぞれ 3 つの API をテストしました。Kubernetes での単一レプリカと 5 つのレプリカの場合をテストしました。API の詳細は以下の通りです:
- 直接返す
- 2 秒待ってから返す
- Elasticsearch の 10000 件のデータをクエリし、各データは 500 バイトです
Elasticsearch クラスタの情報
- ノード数:2
- バージョン:7.4.1
- CPU:8 つの Intel (R) Xeon (R) Silver 4114 CPU @ 2.20GHz、各 1 コア
- メモリ:31G
Kubernetes の情報
- バージョン:1.16.15
- ノード数:7(1 つのマスター、6 つのワーカー)
デプロイメントを同じノードにスケジュールするように指定し、2 つのデプロイメントにはそれぞれ 2G のメモリが割り当てられています。
テスト手順#
Go スクリプトをパッケージ化し、同じディレクトリにconfig.ini
という設定ファイルを作成します。
[address]
null = "POST http://172.17.1.36:30898/hello"
sleep = "POST http://172.17.1.36:30898/sleep"
query = "POST http://172.17.1.36:30898/es"
[param]
rate = 2000
address は呼び出す API のアドレスとメソッドを指し、rate は 1 秒あたりの呼び出し回数を指します(ここでは 1 秒しか呼び出していません)。
スクリプトを実行し、待ちます......
テスト結果#
各 API には 3 つのファイルが生成されます。
- results-*.bin ファイル:テストの生データファイル
- report-*.txt ファイル:レポートファイル
- plot-*.html ファイル:個々の結果のグラフファイル
まずは Java からです。
- 空のインターフェース
Requests [total, rate, throughput] 2000, 2004.21, 1996.25
Duration [total, attack, wait] 1.002s, 997.9ms, 3.98ms
Latencies [min, mean, 50, 90, 95, 99, max] 2.114ms, 28.492ms, 11.283ms, 77.584ms, 90.305ms, 111.482ms, 150.836ms
Bytes In [total, mean] 10000, 5.00
Bytes Out [total, mean] 0, 0.00
Success [ratio] 100.00%
Status Codes [code:count] 200:2000
フィールドの説明
Requests(リクエスト数):
- total は総リクエスト数を示し、ここでは 2000 です。
- rate は 1 秒あたりのリクエスト数を示し、ここでは 2004.21 です。
- throughput は 1 秒あたりの成功したリクエスト数を示し、ここでは 1996.25 です。
Duration(所要時間):
- total はテストの総時間を示し、ここでは 1.002 秒です。
- attack は攻撃時間であり、実際のリクエスト送信時間です。ここでは 997.9 ミリ秒です。
- wait は攻撃中にすべてのリクエストの合計待機時間を示し、ここでは 3.98 ミリ秒です。
Latencies(レイテンシ):
- min は最小レイテンシを示します
- mean は平均レイテンシを示します
- 50、90、95、99 はパーセンタイルを示します。それぞれ 50%、90%、95%、99%のレイテンシです。
- max は最大レイテンシを示します
Bytes In(受信バイト数):
- total はすべてのリクエストの合計受信バイト数を示します
- mean は 1 つのリクエストの平均受信バイト数を示します
Bytes Out(送信バイト数):
- total はすべてのリクエストの合計送信バイト数を示します
- mean は 1 つのリクエストの平均送信バイト数を示します
Success(成功率):
- ratio は成功したリクエストの総リクエスト数に対する割合を示します
Status Codes(ステータスコード):
- codeは各ステータスコードの出現回数を示します。
3 つの結果を統合した場合、レスポンス時間はほぼ線形に増加し、クエリ時間は最後に 3 分以上かかります。
- Go
sleep と空のインターフェースは非常に安定しており、クエリインターフェースのレスポンス時間も Java よりもはるかに改善されています。
次に、5 つのレプリカを追加した場合の 2 つのサービスの結果です。
- Java
sleep インターフェースの安定性が向上し、線形増加しなくなりましたが、クエリインターフェースのレスポンス時間はまだかなり長いです。
- Go
クエリインターフェースのレスポンス時間はあまり改善されませんでした。
結論#
クエリインターフェースに関しては、ボトルネックは Elasticsearch 側にある可能性がありますので、ここではテストしません。
グラフから見ると、Go の並行処理能力は確かにわずかに優れています。
vegeta はまだ使用していない多くの機能がありますが、Jmeter に比べてコマンドラインはあまり使いやすくありませんが、生成される結果は非常に直感的です。