大規模負荷試験時にやったこと
開発部 オンライン開発グループ
土井 聡史
- nonconfidential -
Chapter
INDEX
1. はじめに
2. 負荷試験の準備
3. 負荷試験の実行
4. 負荷試験のチェック項目
5. シナリオ作りでハマった事
- nonconfidential -
1. はじめに
はじめに
- nonconfidential -
本講義では、弊社にて大規模な負荷試験を行った際の
・どのような準備が必要だったのか
・負荷試験実行時に行ったこと
・負荷試験実行時にチェックした項目
といった内容について説明します。
※べき論というよりは、社内で実際に実施した規模の大きな
負荷試験の内容の共有です。
はじめに
- nonconfidential -
・負荷試験とは何か?
・JMeterとは何か?
・JMeterの使い方
といった内容は、他の講義やウェブで検索すると
情報を得る事ができるため、
ここでは割愛します。
- nonconfidential -
2. 負荷試験の準備
負荷試験の準備
- nonconfidential -
まずは負荷試験を実行できる環境を
整えました。
負荷試験の準備
- nonconfidential -
2-1. 環境構築・デプロイ
負荷試験を実施するための環境を作成します。
・本番環境、JMeterを実行するサーバーを構築
・負荷試験を行うアプリケーションを各サーバーにデプロイ
[留意点]
・構築時点でサーバー費用が発生し始めます。
PJ内で合意形成しましょう。
・外部APIと連携している場合は、外部に負荷を
かけてしまわないよう、外部APIとの接続のON/OFFを
容易に切り替えられるように実装しておきましょう。
・データの通信が暗号化される場合も、
暗号化のON/OFFができるようにしておきましょう。
負荷試験の準備
- nonconfidential -
2-2. 負荷試験シナリオの作成
JMeterのシナリオを作成しておきます。
このとき、接続先サーバやスレッドプロパティは、引数で受け取れるよ
うにしておきます。
【例】
JMeter実行時
-Jtargetserver=example.com
とすると、接続先を指定できる
(この例の「marv.jp」は、引数が無
い場合のデフォルト値)
負荷試験の準備
- nonconfidential -
2-3. JMeterシナリオの流れ
JMeterシナリオは、下記のような流れになるよう作成しました。
ユーザー登録(初回登録)
チュートリアル
ホーム画面
カード一覧
ガチャ実行
その他
ループコントローラー
でループさせる事で、
スレッドが生き続ける
(プレイヤーが実際に
ゲームをプレイし続け
ている状況を再現)
ログイン
負荷試験の準備
2-3. JMeterシナリオの流れ
より精度の高いシナリオにするために・・・
機能が揃った段階で、実際にプレイをして
各APIの実行回数の比率を出す
実行回数比率に近い回数で
JMeterのサンプラーが実行されるよう
回数調整を行う
変数をループごとにインクリメントし、
MODを取ってなりして実行回数を調整。
実際のAPI呼び出し回数比率に近づけて
精度を上げる。
負荷試験の準備
- nonconfidential -
2-4. JMeterサーバーのHEAPサイズを調整
JMeterを実行するサーバーのHEAPサイズを増やしておきます。
[JMeterサーバーにて]
jmeterファイルを開き(中身はshell)、
HEAP="-Xms512m -Xmx512m"
HEAP="-Xms512m -Xmx2048m"
ぐらいにしておく。
※これをする事でOutOfMemoryErrorが出にくくなります。
負荷試験の準備
- nonconfidential -
2-5. JMeterサーバー上のスレッド数生成限界を調べておく
JMeterサーバー1台あたり、
スレッドをいくつまで起動できるか
(限界に達するとスループットが上げ止まります。)
調べておくと良いでしょう。
※JMeterシナリオやマシンスペックに左右されますが、
おおよそ 500~1000スレッド(ピンキリです)/台
となるかと思います。
その場合、要求される負荷(rps)/ 限界スレッド数
の台数分、JMeterサーバを構築する必要があります。
負荷試験の準備
- nonconfidential -
2-6. JMeterサーバーでJMeterを効率良く実行できる準備
JMeterサーバーでJMeterを効率良く実行できるよう、
・JMeterサーバ全台へのjmxファイルの同期
・JMeterサーバ全台でJMeterを一括実行
・JMeterサーバ全台でJMeterを一括停止
・JMeterサーバ全台から実行結果ログ収集
できる仕組みを準備しておきます。
JMeterサーバー群
jmxのsync
一括shutdown.sh
一括jmeter実行
ログ収集
- nonconfidential -
3. 負荷試験の実行
負荷試験の実行
- nonconfidential -
3-1. 負荷試験を実行する
ここまで負荷試験の準備を整え、いざ負荷試験を実行すると
ある問題が発生しました。
負荷試験の実行
- nonconfidential -
ユーザー登録(初回登録)
チュートリアル
その他
これが
一気に呼ばれすぎた
ログイン
問題1.
一斉にJMeterを起動すると、ユーザー登録APIが同時に実行さ
れすぎて実態とかけ離れてしまった。
負荷試験の実行
- nonconfidential -
ユーザー登録(初回登録)
チュートリアル
その他
ログイン
【やったこと】
JMeterサーバー毎に順次JMeterが実行されるようにしました。
1番目 2番目 3番目 4番目 5番目 N番目
負荷試験の実行
- nonconfidential -
具体的には、
時間差でJMeterを順次実行していくatコマンドを生成する
シェルを作成しました。
JMeter実行コマンドを
生成し、指定した時間
間隔で各JMeterサーバ
毎にatでジョブキュー登
録するコマンドを生成
するシェルを作成した。
使用するjmx、
台あたりのスレッド
数・RumpUp時間、
開始時刻、
間隔時間、
同時刻に実行する
JMeterサーバ台数
を指定できるようにし
た。
負荷試験の実行
- nonconfidential -
問題2.
負荷試験実施状況の共有が難しくなった。
いま負荷試験
やってるんだっけ?
いま何のシナリオで
負荷試験してるの?
どのぐらいの負荷?
なんか本番重いぞ!
どうなってんだ!!
負荷試験の実行
- nonconfidential -
【やったこと】
負荷試験実施状況が見れるページを作った。
シェルで吐き出した文字列をExcelに
貼り付け、ホワイトボードのように見
れるページを作り、
チームメンバー全員に共有した。
Excel
Browser
- nonconfidential -
4. 負荷試験のチェック項目
負荷試験のチェック項目
- nonconfidential -
4-1. 負荷試験のチェック項目
【共通】
LoadAverage
レスポンスタイム(DB系はインデックス状況含む)
ストレージ状況・ファイル容量
【WEBサーバー】
メモリリーク
エラー出力(Webサーバログ、アプリケーションログ)
【DBサーバー】
メモリリーク
エラー状況
スロークエリログ
スレーブ遅延
CheckPoint Age
【KVSサーバー】
キャッシュ容量
Get misses
【ネットワーク】
転送量
※JMeterサーバにて、JMeterの実行中は・・・
スレッドが増えるごとに、JMeterのスループットが極端に落ちる事が無いか
Errorレートが上がっていないか
を、確認しましょう。
- nonconfidential -
5. シナリオ作りでハマった事
※時間が余っていれば
シナリオ作りでハマった事
- nonconfidential -
5-1. ユーザー定義変数のスコープ
シナリオ内でユーザー定義変数を用いる際、スコープはシナリオ全体なので注意しましょう。
Web JMeter
期待値:
“${result}”!=“hello”
の場合だけ
in_if_1 が定義されて欲しい
結果:
ifの判別結果は偽なのに、
in_if_1 が定義されてしまっている
変数定義でスコープを限定したい場合(コントローラの中だけ、など)は、
ユーザーパラメータを使用しましょう。
シナリオ作りでハマった事
- nonconfidential -
5-1. ユーザー定義変数のスコープ(解決方法)
Web JMeter
期待値:
“${result}”!=“hello”
の場合だけ
in_if_1 が定義されて欲しい
結果:
ifの判別結果は偽なので、
in_if_1 が定義されてない
シナリオ作りでハマった事
- nonconfidential -
5-2. Random Variableの罠
シナリオ内で乱数を複数用いたいとき、Random Variable設定エレメントを複数設定しても、
乱数シードがデフォルトでシステム時間であるため、すべて同じ値になってしまう。
すべて同じ値になってしまう。
シードの値をそれぞれ変えると、今度はループ毎に
毎回同じ値になってしまう。
シードの値欄にRandom関数を書いてもうまく動かない。
シナリオ作りでハマった事
- nonconfidential -
5-2. Random Variableの罠(解決方法)
ユーザー定義変数でRandom関数を使いましょう。
ランダムな値になっている。
値に、下記のように書く
${__Random(最小値, 最大値)}
- nonconfidential -
ご清聴ありがとうございました。

大規模負荷試験時にやったこと