はじめに
はじめまして!クラウドエンジニアのkiyomura(@kiyomura742954)と申します。今回は、ローカルでWordPressを構築して負荷テストをおこなったので、学習したことを記事としてまとめました。
自己紹介
未経験からSIerに転職しまして、クラウドエンジニアとしてAWSの運用保守をしています。エンジニア歴は約1年で、クラウドの技術をもっと身につけたいのとSREについて興味を持ったことがきっかけでTechBullに参加しました。ちなみに熊本在住で地方から参加しています!
負荷試験とは?
負荷試験とは、システムやアプリケーションがどの程度の負荷に耐えられるかを確認することです。これにより、パフォーマンスやスケーラビリティ、そしてシステムの安定性を保証できます。以下が、負荷試験で確認できる重要なポイントです。
- パフォーマンス測定: さまざまなユースケースにおけるシステムのパフォーマンスを評価
- スケーラビリティの確認: システムが負荷に対してどれだけ拡張できるかを検証
- 安定性と信頼性の確認: 長時間稼働させた際にシステムが安定しているか、信頼性があるかを評価
負荷試験ツール
今回の負荷試験ではk6という負荷試験ツールを使用します。k6はJavaScriptでテストスクリプトを記述できて、Grafana製となります。
Apache Benchとk6の違い
メジャーな負荷テストツールにApache Benchがあります。k6とApache Benchを比較してみます。
特徴 | Apache Bench | k6 |
---|---|---|
柔軟性 | 低い(シンプルなHTTP負荷テストのみ) | 高い(JavaScriptで複雑なシナリオも記述できる) |
プロトコルの対応 | HTTP/HTTPSのみ | WebSocket、gRPC、HTTP/2など |
レポート | 基本的なスループットと応答時間のみ。コマンドラインでシンプルなテキスト形式の出力のみ。 | ユーザー定義のカスタムメトリクスが使用可能。結果をJSONで出力して外部ツール(Grafanaなど)と連携可能。 |
Apache BenchはシンプルなHTTPリクエストの負荷テストに適したツールであるのに対して、k6はJavaScriptでシナリオを記述できて、複雑なシナリオの作成や詳細なメトリクスの取得が可能です。
負荷試験の実施
インストール
ローカルにk6をインストールします。MacOSのためHomebrewを使用します。
1 |
$ brew install k6 |
テストスクリプトの記述
1 |
$ k6 new k6-test.js |
k6 new
コマンドで現在のディレクトリにスクリプトのテンプレートを作成することができます。引数にファイル名を指定できます。指定しない場合はscript.jsというファイルが作成されます。以下はテンプレートのコメントアウトを削除して、urlを変更したk6-test.jsファイルになります。今回はMultiPassで開発環境に構築してみたWordPressに対して負荷テストを行ってみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import http from 'k6/http'; import { sleep } from 'k6'; export const options = { vus: 10, duration: '30s', } export default function() { http.get('http://wp.techbull.cloud'); sleep(1); } |
・import http from ‘k6/http’;
httpモジュールのインストール。HTTPリクエストを送信するための関数が含まれています。
・import { sleep } from ‘k6’;
関数 sleepをk6モジュールからインポート。sleepはテスト中に待機時間を設定するための関数です。
・export const options = {}
k6のテストオプションを指定するためのオブジェクト。
・vus
「Virtual Users(仮想ユーザー)」の略。同時にテストを実行するユーザー数を指定する。
・duration
テストの実行時間を指定します。
・export default function()
k6で実行するメイン処理を記述する関数です。関数内の記述が各仮想ユーザーで並行して実行されます。
・http.get(‘http://dev.menta.me’);
指定したURLにHTTP、GETリクエストを送信する
・sleep(1);
1秒間の待機時間 を指定
オプションについて
k6のオプションは、負荷テストの挙動を制御するために設定できる構成項目です。これらのオプションを利用することで、テストシナリオ、仮想ユーザー数、持続時間、ターゲットなどを柔軟に設定できます。
- k6オプションについて、公式ドキュメント
実行結果
作成したスクリプトをk6 runコマンドで実行します。
1 |
$ k6 run k6-test.js |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
/\ Grafana /‾‾/ /\ / \ |\ __ / / / \/ \ | |/ / / ‾‾\ / \ | ( | (‾) | / __________ \ |_|\_\ \_____/ execution: local script: k6-test.js output: - scenarios: (100.00%) 1 scenario, 10 max VUs, 1m0s max duration (incl. graceful stop): * default: 10 looping VUs for 30s (gracefulStop: 30s) data_received..................: 15 MB 495 kB/s data_sent......................: 21 kB 682 B/s http_req_blocked...............: avg=22.61ms min=2µs med=7µs max=612.76ms p(90)=15.1µs p(95)=19.54µs http_req_connecting............: avg=221.55µs min=0s med=0s max=8ms p(90)=0s p(95)=0s http_req_duration..............: avg=119.4ms min=23.84ms med=65.81ms max=1.51s p(90)=96.32ms p(95)=118.01ms { expected_response:true }...: avg=119.4ms min=23.84ms med=65.81ms max=1.51s p(90)=96.32ms p(95)=118.01ms http_req_failed................: 0.00% 0 out of 270 http_req_receiving.............: avg=2.06ms min=610µs med=1.57ms max=12.33ms p(90)=3.57ms p(95)=5.3ms http_req_sending...............: avg=25.57µs min=6µs med=21µs max=248µs p(90)=46µs p(95)=61µs http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s http_req_waiting...............: avg=117.31ms min=22.72ms med=63.04ms max=1.51s p(90)=95.42ms p(95)=115.91ms http_reqs......................: 270 8.746621/s iteration_duration.............: avg=1.14s min=1.02s med=1.06s max=3.12s p(90)=1.09s p(95)=1.11s iterations.....................: 270 8.746621/s vus............................: 10 min=10 max=10 vus_max........................: 10 min=10 max=10 running (0m30.9s), 00/10 VUs, 270 complete and 0 interrupted iterations default ✓ [======================================] 10 VUs 30s |
・data_received
総受信データ量
・data_sent
総送信データ量
・http_req_blocked
httpリクエストが送信されるまでの待機時間(TCP接続スロットが利用可能になるまでの待機時間)
・http_req_connecting
リモート ホストへの TCP 接続を確立するのにかかった時間。
・http_req_duration
1つのHTTPリクエストの合計所要時間。(DNS解決時間や接続確立時間 (TCP handshake や TLS handshake)は含まれない)
・http_req_failed
失敗したHTTPリクエストの割合。setResponseCallback関数によってカスタマイズできる。
・http_req_receiving
リモートホストからの応答データを受信するのに要した時間。
・http_req_sending
クライアントがリモートホストにデータを送信する時間。
・http_req_tls_handshaking
リモートホストとの TLS セッションのハンドシェイクに費やされた時間(TLSハンドシェイクとはクライアントとサーバーが安全な通信を確立するための手続きのこと)
・http_req_waiting
クライアントがリモートホストから応答を待機している時間。(time to first byteまたはTTFBとも呼ばれます)
・http_reqs
k6 が生成した HTTP リクエストの合計数。
・iteration_duration
1回の反復(イテレーション)を完了するのに要した時間。セットアップや後処理(setup / teardown)も含む。
・iterations
仮想ユーザー(VUs)がテストスクリプトのdefaul関数を実行した合計回数 をカウントする指標です。
・vus
現在アクティブな仮想ユーザー数。
・vus_max
仮想ユーザーの最大可能数 。
メトリクスについて
メトリクスには、組み込みメトリクス(k6にデフォルトで組み込まれているメトリクス)とカスタムメトリクス(ユーザーが独自に定義できるメトリクス)があります。今回は標準の組み込みメトリクス(使用されるプロトコルに関係なく収集されるメトリクス)とHTTP固有の組み込みメトリクスが出力されています。
- k6メトリクスについて、公式ドキュメント
テスト結果
出力されるメトリクスの種類が多く、どれを見ればいいのか分かりませんでしたが、公式ドキュメントには、まず以下の指標から測定を始めることを推奨する記載がありました。そのため、これらを基に測定を進めてみようと思います。ちなみにこれはREDメソッドという監視フレームワークの指標みたいです。
- http_reqs、リクエストを測定する
- http_req_failed、エラー率を測定する
- http_req_duration、期間を測定する
1 |
http_reqs......................: 270 8.746621/s |
- 合計リクエスト数: 270
- リクエストレート:8.75リクエスト/秒
1 |
http_req_failed................: 0.00% 0 out of 270 |
エラーなく全てのリクエストが成功しているので問題なさそうです。
1 |
http_req_duration..............: avg=119.4ms min=23.84ms med=65.81ms max=1.51s p(90)=96.32ms p(95)=118.01ms |
- 平均: 119.4ms
- 最小: 23.84ms
- 中央値: 65.81ms
- 最大: 1.51秒
- p(90): 96.32ms (全リクエストの90%がこの時間以下)
- p(95): 118.01ms (全リクエストの95%がこの時間以下)
95%のリクエストは118ms以下で処理されているので、こちらも問題なさそうです。
まとめ
負荷試験を通して、システムのパフォーマンスや安定性を確認する手法を知ることができました。またテストで使用したHTTPプロトコルの動作についても勉強になりました。今回はk6の簡単なスクリプトを実行しただけなので、より複雑なテストシナリオやレポートの出力などにもチャレンジしてみたいです。
未経験からSIerに転職し、現在クラウドエンジニアとしてAWSの運用保守をしている。エンジニア歴は約1年で、クラウドの技術をもっと身につけたいのとSREについて興味を持ったことがきっかけでTechBullに参加。ブログでの執筆をメインに担当している。