作成日:2025-04-01, 更新日:2025-04-10
一般的なシナリオ
- アクセス数による確認
- ユーザーの挙動による確認
アクセス数による確認
任意のページに同時アクセスして確認。ある程度、通常のアクセス数を把握・想定する必要がある
- アクセス増加の確認
- 「急激なアクセス増加」の確認が「スパイクテスト」
- 「徐々にアクセス増加」の確認が「スケーラビリティテスト」
- 長時間のアクセスの確認
- 「通常のアクセス数が長時間続く場合」の確認が「持続負荷テスト」
- 「多いアクセス数が長時間続く場合」の確認が「ピークトラフィックテスト」
ユーザーの挙動による確認
一般的なECサイトを想定した場合、「ログインして、対象ページを開き、商品をカートにいれ、決済」を実行させて確認
- 実際の動きにあわせた確認が「エンドツーエンドの負荷テスト」
負荷テストで使う会員の問題
理想は...
- 負荷テスト用に会員を用意
→大量に登録できるような仕組みを別途用意 or がんばって手動で登録 - 負荷テストが終われば削除
→大量に削除できるような仕組みを別途用意 or がんばって手動で削除 or 削除せず放置 or DBの各テーブルをクリア
※会員の削除が論理削除なら物理削除のメソッドを別途用意
負荷テストを行う際の注意点
アクセス負荷をかけるので、環境に気をつける
→レンタルサーバなら各種制限のチェックは必要と思う
負荷テストを行うツール
JMeter、LoadRunner、Gatling、Locust、k6などがあるっぽい
Apache JMeter
JMeterってツールで負荷テストしてみる
※参考: 誰にも迷惑をかけずにJMeterを動かす一番シンプルなやり方
準備
- JAVAをインストしておく
- Apache JMeterのサイトからソースをダウンロード、解凍、実行
※「bin/jmeter.bat」を実行
※日本語化したいけど、分からないことがあったとき、どうせ英語サイトばっかりだから英語のままにしておく(「Options - Choose Language - Japanese」で日本語化)
テストの作成:お試し
- スレッドグループを作成
- 実行内容を作成(お試し)
- 結果の準備
- テストの保存、実行
- 結果の確認
スレッドグループを作成
「Test Plan」を選択し、「Edit - Add - Threads(Users) - Thread Group」でスレッドグループを作成
- Number of Threads - 人数: お試しテストなんで「1ユーザー」
- Ramp-up period - 全員が実行開始するにかかる時間: お試しテストなんで「1秒」
- Loop Count - 実行回数: お試しテストなんで「1回」
実行内容を作成(お試し): httpリクエストの作成
「Test Plan - Thread Group」を選択し、「Edit - Add - Sampler - HTTP Request」でリクエストの設定
「Protocol、Server Name、PATH」を設定する
※「https://example.test/hoge」の場合、「Protocol - https, Server Name - example.test, PATH - hoge」。「Protocol - https, Server Name - example.test/hoge, PATH - [空白]」はダメっぽい
結果の準備
「Test Plan」を選択し、「Edit - Add - Listener - Aggregete Report」で結果を準備
テストの保存、実行
いったん、ここまでの内容を保存しておく
「File - Save」や「File - Save Test Plan as」
結果の確認
実行して、先ほど保存した「Aggregete Report」を確認
Graphite
「Aggregete Report」以外にとりえあず「Summary Report」「View Results Tree」「Backend Lister」も追加してテストを実行すると下記エラーがでてきた
2025-04-01 16:10:00,843 ERROR o.a.j.v.b.g.TextGraphiteMetricsSender: Error writing to Graphite: connect timed out java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) ~[?:1.8.0_361] ...
Graphiteサーバーってヤツに接続できない...的なエラーらしい
そもそも、「Graphiteサーバー」って何?って調べたら監視ツールみたいなヤツらしい
さらに調べるとJMeterが「Graphiteサーバー」にリクエストをしているってトコまでは分かったけど、それを無効にしたい
調べると...有効にする方法はあるけど、無効にする方法が見つけられず...ガンバって調べたら「Aggregete Report」以外にとりえあず追加していた「Backend Lister」ってヤツが原因ということがわかった
→とりあえず、削除して解決
テストの作成:ログイン処理
ログインの負荷テストをつくってみる...挫折したけど...
- httpリクエストを追加: /login, get送信
- 正規表現抽出を追加: csrfトークンを取得
- httpリクエストを追加: /login/do, post送信
上記のような感じでいけるんだけど...送信前にAPIでバリデーションチェックを実行していて、csrfトークンがワンタイムトークンなんだなぁ...JMeterでもどうにか出来るっぽいけどタイヘンそうな感じなので挫折...
本来やりたい流れは下記のような感じ
- httpリクエストを追加: /login, get送信
- 正規表現抽出を追加: csrfトークンを取得
- httpリクエストを追加: /login/validation, post送信
- csrfトークンを再生成 ← ココがjavascriptで実行しているのでよく分らん
- httpリクエストを追加: /login/do, post送信
正規表現の抽出
「Edit - Add - Post Processors - Regular Expression Extractor」で設定
「Name of created variable」ってのが参照名になるので、httpリクエストのパラメータの値で使う
使うときは「${}」で囲んでやる必要がある
テストの作成: 同時アクセス
「5秒以内に500ユーザーがアクセスしてきて、1時間、サイトを利用した」とする
→タイマーをセットする必要がある
「Edit - Add - Timer」で「Constant Timer(一定時間ごと)」「Gaussian Random Timer(ランダム)」から設定
シナリオ: 2秒に一回アクセス
5秒以内に500ユーザーがアクセスしてきて、2秒ごとにアクセスを1時間繰り返した
「2秒に1回」で「1時間」なので「ループ回数 = 3600 / 2 = 1800回」
- スレッド数 - 500人
- Ramp-Up 期間(秒) - 5秒
- ループ回数 - 1800回
Constant Timer
- Thread Delay - 2000ミリ秒
シナリオ: 3~10秒にアクセス
5秒以内に500ユーザーがアクセスしてきて、3~10秒ごとにアクセスを1時間繰り返した
「3~10秒に一回アクセス」なので「平均 = (3+10)/2 = 6.5秒」
「1時間実行」なので「ループ回数 = 3600 / 6.5 = 554回」
- スレッド数 - 500人
- Ramp-Up 期間(秒) - 5秒
- ループ回数 - 554回
Gaussian Random Timer(正規分布(ガウス分布))
「Deviation (偏差)」と「Constant Delay Offset (一定遅延オフセット)」を設定する必要がある
→「Deviation」がプラスマイナスの値で、「Constant Delay Offset」が基準の値となる
「3秒~10秒」なので、
・Deviation = ((10-3)/2)*1000 = 3.5*1000 = 3500ミリ秒
・Constant Delay Offset = ((3+10)/2)*1000 = 6.5*1000 = 6500ミリ秒
→6.5秒を基準(Constant Delay Offset)にプラスマイナス(Deviation)3.5秒
- Deviation (偏差) - 3500ミリ秒
- Constant Delay Offset (一定遅延オフセット) - 6500ミリ秒
→「6500ミリ秒 - 3500ミリ秒」~「6500ミリ秒 + 3500ミリ秒」で「3~10秒」となる
テストの結果
設定次第で色々と異なるらしいので、よくわからん
とりあえずThroughput(スループット)ってが重要な気がする
Throughput
Throughputってのが毎秒のリクエスト数になるそうだ
→想定ユーザー数、各ユーザーの滞在時間・閲覧ページ数などから秒単位のリクエストを算出。それより大きいなら問題なし。小さいなら高負荷になっていると思われる
小規模なECサイトなら、秒間数リクエストから十数リクエスト。比較的少数の同時ユーザー(数十人から数百人)を想定した値
※Throughputは10/sec~15/secあたり
サーバ負荷の確認
とりあえずサーバ負荷を知りたいのでサーバ側でシステムのパフォーマンスを監視するのが良さげ
linuxでリアルタイムで目視するなら「top」、あとで確認するなら「vmstat」
→目視で異常を発見できる自身は皆無なので「vmstat」を使う
▼毎秒データを保存。終了したければ「ctrl + c」
$ vmstat 1 > vmstat_20250401_1420.txt
▼毎秒データを保存。10分で処理終了
$ timeout 600 vmstat 1 > vmstat_20250401_1420.txt
見るところ
- 「cpu」の「wa(wait time)」が高いとディスクやネットワークの問題あり
- 「swap」の「si(swap in)」と「so(swap out)」が高いとメモリ不足の問題あり
メモ
ニュアンスが異なってたり、微妙に違ったり、完全に間違ってたりするかもしれないけど、ひとまず...とりあえず自分の中で確定させて必要に応じて認識を改める
- 負荷テストにおける「スレッド数」とは「ユーザー数、セッション数」と同義
- Ramp-Up 期間(秒)は、スレッドを一つずつ開始するときの時間差
※「実行開始時間 = Ramp-Up 期間(秒) ÷ スレッド数」- スレッド数1、Ramp-Up期間10秒なら0秒後に実行
- スレッド数2、Ramp-Up期間10秒なら0秒後と5秒後に実行
- スレッド数5、Ramp-Up期間10秒なら0秒後から2秒ごとに実行
ループ回数は同じ処理を繰り返すだけだから、終了時間は処理内容によるのでケースバイケース
→ 一般的なECサイトの負荷テストで「シナリオ: セール開始直後に1000人が同時アクセス」を想定した場合、「スレッド数1000、Ramp-Up期間1秒、ループ回数1」のような感じ - 「エンドツーエンドの負荷テスト」と「スパイクテスト、スケーラビリティテスト、持続負荷テスト、ピークトラフィックテスト」を組み合わせるのが基本
- 「持続負荷テスト」は運用当初のサービスが軌道に乗る前を想定
- 「ピークトラフィックテスト」はサービスが軌道にのった後を想定
- 「スパイクテスト」は運用スタート時や何かしらの告知・宣伝をしたときを想定
- 「スケーラビリティテスト」は炎上したり、告知・宣伝の影響が継続しているときを想定
- 負荷テストの結果を見るときにとりあえず抑えておくべき点
- Throughput:
判断をする前に想定ユーザー数、各ユーザーの滞在時間・閲覧ページ数などから秒単位のリクエストを算出。
それより大きいなら問題なし。小さいなら高負荷になっていると思われる - vmstatで確認する点:
・「cpu」の「wa(wait time)」が高いとディスクやネットワークの問題あり
・「swap」の「si(swap in)」と「so(swap out)」が高いとメモリ不足の問題あり
- Throughput:






