#navi_header|技術| Apache JMeter の使い方メモ。2007-2008頃にまとめたメモなので、内容的に古いかもしれません。 ※Javaアプリケーションなので、事前にJavaの実行環境をインストールしPATHを通しておく。JREだけでOK。JDK(SDK)までは必要ない。 #more|| #outline|| ----- * 参考URL - Apache JMeter -- http://jakarta.apache.org/jmeter/ - TECHSCORE -- http://www.techscore.com/tech/ApacheJakarta/JMeter/index.html * 入手とインストール、設定 http://jakarta.apache.org/jmeter/ より "Download Binary"をクリックして、JMeterをDLする。 今回はバージョン 2.3.1 のzip圧縮パッケージをDLした。 DLしたzipファイルを展開すると、以下のようなディレクトリが解凍される。 jakarta-jmeter-2.3.1/ bin/ docs/ extras/ lib/ printable_docs/ bin/jmeter.bat をダブルクリックすると、Windows上でGUIモードのJMeterが立ち上がる。 なおjmeter.bat中にはJVMのパラメータを設定するためにいろいろと変数が設定・利用されている。必要に応じて適宜Hackするとよいかも。只GC系については下手に弄ると却って悪化することもあり怖いので、通常はデフォルトのままで良い筈。 * 実践的なテストケースの構築 ** なによりも添付のUser's Manualを熟読。 展開して出来たディレクトリ中に、英語ですがUser's Manualが添付されています。 docs/usermanual/index.html 英語ですが、これが実際の所一番詳しいドキュメントになります。 *** 最初に読む英語ドキュメント User's Manualで最初に読んでおくべきところは、以下の 3. - 6. になります。 - 3. Building a Test Plan - 4. Elements of a Test Plan - 5. Building a Web Test Plan - 6. Building an Advanced Web Test Plan ThreadGroupという独特の単位や、実行順などテストケースを組み立てる上で必須の知識が何気なく書かれていますので急がば回れで、一度通して読んでおいた方が良いです。 *** 重箱の隅をつつくように読むべき箇所 User's Manualではいくつか、リファレンス的なページがあります。で、実はそこは重箱の隅をつつくように、丹念に読み込む必要があります。英語ですので何気なく流し読みしてると飛ばしてしまいそうな一文が、実は結構重要なポイントだったりします。 ''特に背景色付きのボックスで囲まれた一文は注意してください。'' - 18. Component Reference - 19. Functions これなどが、実際にテストケースを組み立てていると頻繁に参照することになります。 また、「21. Glossary」には"Latency"と"Throughput"の用語説明があります。何となく使いがちな用語ですので、JMeterにおける意味を確認するためにも一度目を通しておくべきでしょう。 ** JMeterのプロキシ機能を使ったテストケース作成 すでにテストすべきアプリケーションが一通りできあがっており、ログインやログアウト、ログインした後のユーザーのクリックするルートなどある程度固まっている場合には、JMeterのプロキシ機能を使ってブラウザの動きをそっくりキャプチャしてしまいます。 基本的な流れは http://www.techscore.com/tech/ApacheJakarta/JMeter/6.html に書いてある通りですが、いくつかより実践的なところを紹介します。といってもUser's Manual読めば載っている程度なんですが。 *** テストプランの保存先コントローラの指定 付属User's Manualの「18. Componnent Reference」の「18.9.5 HTTP Proxy Server」、「Where Do Samples Get Recorded?」に書いてありますが、キャプチャ結果をSamplerに変換した結果の保存先を調整可能です。 "Test Plan"にスレッドグループを適当に作成し、その中に「記録コントローラ」(Recording Controller)を追加しておきます。あるいは任意の箇所に記録コントローラを作成しておきます。 TECHSCOREの記事では省略されていますが、HTTPプロキシエレメントの"Target Controller"(対象となるコントローラ)で、プルダウンメニューの中にキャプチャした結果を保存するためのコントローラ一覧が出てきますので、そこで、作成しておいた任意の記録コントローラを指定できます。 *** ユーザー定義値による自動置換 付属User's Manualの「16.4 Using the Proxy Server」でも触れられていますが、ユーザー定義値を用いてホスト名を自動的に "${server}"などに置換してくれます。 ''これはもう、必須といって良い手法です。'' やり方は、プロキシエレメントのTarget Controllerで指定したコントローラのスレッドグループ or テストプラン全体で、例えばブラウザ上から流すときのホスト名などをユーザー定義値としてあらかじめ用意しておきます。 name : ${TARGET_HOST} value : www.example.com こうしておくと、プロキシがWebブラウザのリクエストをキャプチャしてサンプラに変換するとき、www.example.comという文字列を "${TARGET_HOST}"に逆変換してくれます。これで、キャプチャしたサンプラを一つずつ開き、ユーザー定義値を調整する労苦から解放されます。 ** ページに含まれるCSS, JavaScript, イメージファイルもダウンロードさせるには HTTP Request サンプラの「全てのイメージとアプレットを繰り返しダウンロードする」にチェックをつけます。 (英語だと"Retrieve All Embedded Resources from HTML Files"になります) なお、テスト対象となるサーバー以外のイメージやJavaScriptは除外したい・・・というような場合は、その下にある 「Embedded URLs must match:」欄にダウンロード対象となるURLを正規表現で設定しておきます。 ** ページ中に特定パターンで含まれるリンクをクロールさせたい 例えばページナビゲーション部分(1, 2, 3, ...と並ぶ箇所)や、一覧表示ページでの詳細画面へのリンクURLなどをクロールさせたいときがあると思います。 そうした場合はForEachコントローラ(ForEach Controller)と、正規表現抽出(Regular Expression Extractor)のコンビネーションが効果的でしょう。正規表現抽出は「後処理」(Post-Processor)に分類されるエレメントで、HTTPリクエストSamplerを右クリック→「後処理」→「正規表現抽出」で追加できます。 設定方法の詳細はここで文字を費やすよりも、添付User's Manualの「18. Component Reference」→「18.2.12 ForEach Controller」に、どんぴしゃりのサンプルと解説が絵入りで載っていますのでそちらを参照してください。 * 嵌りどころ 基本的にUser's Manualに書いてあるところをうっかり読み飛ばしていたのが原因で嵌ってしまうのが非常に多かったような気がします。 ** ユーザー定義変数はスレッドグループ間でグローバル。 複数台同時に同じテストケースを流す場合、人情としては、 + スレッドグループにユーザー定義変数でホスト名を指定しておき、 + スレッドグループを丸ごとコピーして、 + 各スレッドグループ毎のユーザー定義変数のホスト名だけ返ればオッケー。 と思ってしまう所なんですが。 実はユーザー定義変数はスレッドグループ間でグローバルになっています。つまり上のようにやってしまうと、最後のスレッドグループのユーザー定義変数の設定が、全スレッドグループで使われてしまいます。 実はこれについても添付User's Manual の「18. Component Reference」、「18.4.13 User Defined Variables」に色つき囲みでちゃんと If you have more than one Thread Group, make sure you use different names for different values, as UDVs are shared between Thread Groups. と書いてあったりします。というわけで、「18. Component Reference」は結構細かいところまで読まないと危ないです。 というわけで、あまりスマートじゃないのですがテストプラン自体のユーザー定義変数に、用意するスレッドグループ分のホスト値を ${server1}, ${server2}, ${server3}, ... という具合に用意しておき、しかも、スレッドグループをコピーしたらそこを逐一、書き換えていく・・・という厭な作業をこなすほか無いようです。 ** サーバーを立ち上げた直後の一回目は信用しない 少しJMeterの話題からずれますが・・・結局、電源を入れてOSが起動し、サービスが立ち上がった直後はメモリ状態も「クリーン」な状況ですし、各サービスの内部状態もまだ最適化されていない状態です。Apacheのプロセスは初期状態ですし、DB系は内部メモリのキャッシュヒットも空っぽだと思います。 そのような状態での一回目は、結局実稼働状況とは異なる状態ですので、実際の値としては信頼できないと思います。 一回目はウォームアップというか「ならし運転」として、実行はするけど値は捨ててしまい、二回目以降を実際の値として取った方が良いです。というか実際に、一回目で、本来だったら安定点を超しているはずのスレッド数でも良い値が出てしまい、何度か別の状況でこなしたあとに再度やってみると全然一回目ほどは出ず、というかそちらこそが本来の値だった・・・という経験をしたことがあります。 ** ApacheのKeep-Aliveに注意 というか複数のサーバーを同時にターゲットするときは、設定ファイルの内容がずれていないか注意しましょう、という事になりますが・・・。 ともあれ、ApacheのKee-Aliveは有効にしておくべきです。Keep-Aliveを無効にしていたため、ものすごいデータがばらつき、スレッドがブロックされてJMeterをうごかしているマシンのCPU使用率が100%で止まってしまったりとかすごい状況になってしまいました。 ** 数百単位のスレッドでWindows上でJMeterを動かすときの注意事項 ここまでやるのなら、普通は複数マシンに分散させてnon-guiモードでやると思いますが・・・。 ともあれ。Windowsでは一般のプログラムが使用できるポートの最大値がレジストリにより制限されています。また、このスレッド数のレベルでしかも十分速くリクエストが走ってしまうと、ソケット接続のタイムアウト値(ソケットがcloseされたあと、ディスクリプタが完全に消去されるまでのTO)に到達しないうちに、つまり古いclose済みのソケットで一杯の状態で新しくソケットを作ろうとして、前述のポート最大値に到達してこけてしまう・・・など、そういった現象が発生しやすくなるようです。 例えばポートの最大値が5000だとすると、一旦5000に達するとWellKnownPortの次あたりに巻き戻り、1000番台、2000番台へとクライアントポートが巻き戻ります。というわけで、コネクションが消えるだけの時間的余裕がある状態であれば、その中でぐるぐるループするのですが、コネクションが消えない段階でループしてしまうとポートが全部埋まってしまい、ソケットをBINDできなくてこけるようです。 実際にそうした現象は結局発生しなかったのですが、Windows上でのTCP/IPソケットの設定値を修正するというのは他の局面でも役に立つTipsだと思いますので、参考URLなどを載せておきます。 - http://data.blogdns.net/blog/2005/06/jmetersocket.html - http://d.hatena.ne.jp/oreflow/20070906 - http://msdn2.microsoft.com/ja-jp/library/aa560610.aspx - http://www.microsoft.com/japan/technet/archive/prodtechnol/iis/iis4/maintain/optimize/iistun.mspx - http://www.microsoft.com/japan/technet/itsolutions/network/deploy/depovg/tcpip2k.mspx - クライアントの TCP/IP ソケット接続に動的に割り当てられる一時的なポートの上限を引き上げる。 -- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort - クライアントの TCP/IP ソケット接続のタイムアウト値を既定値の 240 秒よりも短くする。 -- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay ** スレッドグループのループを有限にしていた時、終わりまで流さず途中で切り上げよう。 最後まで流してしまうと、全ループ終了後のスレッドクリーンアップで特にグラフ表示のリスナーで、値がむちゃくちゃになります。つまり最後にスループットが一気に落ち込み、分散も跳ね上がり、値として使い物にならなくなります。 ループを有限にしている場合は、終わる一歩手前か、ある程度値が落ち着くサンプル数を把握しておき、適当なタイミングでシャットダウンさせる方が良いでしょう。 ** グラフ表示リスナーで、表示がループして最初の頃のと重ねて表示されてしまいます。 そういう仕様っぽいです。 * グラフ表示リスナーなどで出てくる統計用語について グラフ表示リスナーには - 平均(Average) - 中央値(Median) - 偏差(Deviation) - スループット(Throughput) という気になる用語が表示されています。Wikipediaや統計入門的なページから引っ張ってきた知識を大胆にまとめると・・・ : 平均 : Latencyの相加平均。全部足してNで割った値。Latencyについては添付User's Manualの「21. Glosarry」参照。 : 中央値 : 標本をずらっと並べたときの、真ん中に位置する値 : 偏差 : 分散の正の平方根で、各標本の平均値からのずれ : スループット : JMeter独自の定義に基づく。添付User's Manualの「21. Glosarry」参照。 注意すべきは偏差で、これが異常に大きくなると、リクエストにかかる時間がリクエスト毎に極端にぐちゃぐちゃになっている状態ですので、サーバー自体がおかしいです。設定がおかしくなっていないか(KeepAlive無効?)、デッドロックが走ってないか、など、とにかく何らかの異常が発生しているはずです。 #navi_footer|技術|