GMOメイクショップ コアグループ エンジニアの森です。
現在のチームではずっと次世代ECのフロントエンドをメインに開発してきましたが、最近バックエンド開発も触るようになってきました。
そんな中、直近の業務で作成したAPIに対する負荷試験を担当しました。私にとっては初めての負荷試験だったのですがk6というツールを使うと簡単に実施できたので、その手順を書いていきます。
私と同じような初心者の助けになれば嬉しいです。
負荷試験とは
負荷試験は、実際に発生し得るシステムへのアクセス等を想定した負荷がかけ、それに耐えられるか等を確認する試験です。大量のアクセスがかかった場合や、長時間連続稼働し続けた場合にシステムに異常が発生しないか等を検証します。
k6とは
k6はオープンソースの負荷試験ツールです。JavaScriptを使ってテストシナリオを作成し、簡単に負荷試験を実施することができます。
有料のクラウド版もありますが、今回はローカルマシンで実施します。
試験実施
1.シナリオ作成
今回は具体例として、私が実施した負荷試験のシナリオから
[ショップ情報取得] → [会員ログイン]
の処理部分を抜粋してシナリオテストの例を見ていきましょう。
まずはショップ情報取得する処理です。
このAPIは情報を取得するために複数のエンドポイントを叩く必要があるので、配列にしてループでhttp.get()
でAPIを実行しています。
APIレスポンスからcheck()
今回はAPIレスポンスを確認してステータスが200なら成功、それ以外が返ってきたら失敗と判定するよう定義します。http
、check
共にk6に含まれるモジュールですのでimportする必要があります。
続いてログイン処理ですが、先程と同じようにエンドポイントを叩きcheck()
でAPIの成否を確認します。
ただしログインにはID/PWの確認が必要ですのでhttp.post()
を使用してリクエストします。
最後にこれらを順番に実行するメソッドを作成すればテストシナリオの完成です。
2.オプション
k6 では実行時間などをオプションとして設定できます。実行コマンドに書き込んで指定することができますが、ソースに書き込むことも可能です。ソースに書き込んでおけば、毎回コマンド実行時に書く必要もなく、また記録として残しておくこともできるので便利です。
今回は以下のように設定しました。
上から順に見ていきます scenariosの負荷試験の実行オプションを設定。
executor: "constant-vus"
:リクエストするペース、今回は一定の負荷をかけ続けるよう設定exec: "default"
:実行するメソッド名、defaultの場合はなくても問題ありません。- execの名前が間違っているとエラーが返ってきます。
ERRO[0000] There were problems with the specified script configuration:
vus: 1
:同時接続数、今回は1に設定duration: "10m"
:実行時間、今回は10分に設定
詳しくはドキュメント参照
thresholdsには負荷試験の合格条件を記述します。プロジェクトに合わせて適切に設定してください。
http_req_failed: ["rate<0.05"]
:リクエストのエラー率が5%未満
(IPAの非機能要求グレードの性能目標値のオンラインレスポンス:レベル4に設定)http_req_duration: ["p(95)<3000"]
: // 95%のレスポンスが3秒以内で正常に処理できていること
詳しくはドキュメント参照
最終的なシナリオテストのコードは以下のようになりました。
3.実行コマンド
先程作ったシナリオテストは、以下コマンドで実行できます。
実行コマンドに追加できるオプションがいくつかありますが、今回使って便利だったものを紹介します。
-v
:デバッグモードで実行、console.log()等が出力される- エラーが発生した際、console.log()でレスポンスの中身を確認する際に役立ちました。
--out
:実行結果をファイル出力する- データとして残せますし、エラー出ていた時間帯のログを確認する等役立ちました。
以下、output.jsonにconsole.log()の出力等を含めて出力するコマンドです。
4.実行結果
以下が作成したシナリオテストの実行結果です。
以下は各check()
の結果を示しています。今回はすべてのAPIが成功しているので、すべてにチェックをついています。
その下に項目.......結果
の形式で試験結果が表示されます。一部抜粋です。
http_req_duration
はリクエストにかかった時間とthreshold
の定義に対する合否を表示しています。 今回の95%が3秒以内で定義したので p(95)の部分を見てみると、約0.2秒以内にリクエストが完了しており合格判定なので✓がついています。
http_req_failed
はリクエストの失敗率とthreshold
の定義に対する合否を表示しています。
今回は失敗率0.00%(0件失敗、5484件成功)、5%未満で合格なので✓がついています。
今回は各APIにエラーが見られず、試験の合格条件を満たしているのでこの負荷試験では問題なしと言えそうです。
5.実行結果(エラー例)
先ほどはリクエストが全て上手くいったパターンの結果でしたが、リクエストにエラーが発生してしまった場合の結果も見てみまししょう。
以下は先程のシナリオテストのうち、ログイン処理の何割か失敗させた場合の結果です。
失敗した場合は以下のように各check()
毎に成功率 — ✓ 成功数 / ✗ 失敗数
が表示されます。
リクエストの失敗率が26.49%、thresholdsで定義したエラー率5%を上回ったためhttp_req_failed
に✗がつき、最後にエラーメッセージが表示されています。
http_req_duration
はかかった時間だけ見ているのでエラー率とは関係なく合格になっています。
タイムアウトエラー等、時間がかかる類のエラーだった場合はここにも✗がつきそうです。
まとめ
k6を使うと簡単にシナリオテストを作成し、負荷試験を実施することが可能です。
今回は簡単な例のみ紹介しましたが、オプションの同時接続数や実施時間を変更することで限界性能や連続稼働の検証も可能です。
今回は負荷試験の結果を出すまでの流れを紹介しましたが、実際の負荷試験ではシナリオテストの結果に対して不合格だった場合やエラー等発生していた場合には、問題の特定・分析やパフォーマンスチューニング等が必要になります。 こちらに関しても今後記事にしていければと思います。
最後まで見ていただき、ありがとうございました。
◆ 他のBlogはこちらから⇒ https://tech.makeshop.co.jp/ ◆
ご応募お待ちしています!