Apache JMeter で Web サーバのチューニング

最近、VPS が現実的な値段になってきまして root ありのサーバで LAMP 構築して WordPress なんてこともちょっとがんばればできるようになってきました。

そこで、はてさて安価な VPS どれくらいの性能が出るのかってことでまずはローカルの仮想環境で同じスペックのサーバをたてて試験して、、、みたいなんてときに使えるかなと思い、Web の負荷やシナリオ試験アプリケーション Apache JMeter の使い方とか書いてみたいと思います。

ここでかかれていることはローカル環境向けです。 他の方も使っているインターネットサーバに向けては決して負荷試験は行わないでください。

というわけで、とりあえず Apache JMeter。 pure Java のアプリです。 swing ベースなのでちょっと使いづらいですが、Java が動く環境なら動作すると思います。 ぼくは Linux と Windows で試しています。

JMeter – Wikipedia

Apache JMeter(アパッチ ジェイメーター)は、Jakarta Projectにおいて開発されたソフトウェアで、クライアント・サーバシステムのパフォーマンス測定および負荷テストを行うJavaアプリケーションである。

オープンソースかつ多数の機能を備えていることなどから、WebアプリケーションおよびWebサーバの性能測定に広く利用されている。

JMeter – Apache JMeter

Apache JMeter is open source software, a 100% pure Java desktop application designed to load test functional behavior and measure performance. It was originally designed for testing Web Applications but has since expanded to other test functions.

JMeter を起動したらシナリオを作成していきます。

ここでは、WordPress サイトに対して秒間 50 人くらいのアクセス集中を想定してみます。 とりあえず右ペインを以下のように。

jmeter01

名称はデフォルトのままにしていますので、「テスト計画」の右クリックからアイテムを探して追加していきます。 上からいきます。

CSV Data Set Config。

jmeter02

これは任意の csv ファイルから動的な項目を読み取る場合に使います。 子要素にループがあると上から値が読み込まれていきます。 なくなると上に戻るようです。 ここでは wp.csv としていますがこれは以下のようにアクセスするパスを指定しています。 path という名前をつけているのに注目しておきます。

wp.csv

gallery
about
archives/1134
archives/1124

次は、 HTTP ヘッダマネージャ。

jmeter03

ブラウザを疑似るために、それっぽいヘッダをつけておきます。 まぁ全部なくてもいいと思いますが、Web サーバがブラウザだと思ってくれるようにしておきます。

HTTP リクエスト初期値。

jmeter04

この後にでてくる HTTP リクエストの初期値を設定しておきます。 これを設定した後はリクエストの設定済みの欄を空で、この値が使われます。 ぼくらはローカルと結合環境、統合環境などと工程によって試験環境を分けることが多いのですが、そういうときに振り先をすぐ変更できるので便利です。

ここからが本題、スレッドグループ。

jmeter05

スレッドグループに所属する子要素が同時に実行されます。 スレッド数が同時に上がる数で Ramp-Up 期間がそれをどれくらいの時間で実現するかとなります。 この場合は、1秒に 50 アクセスを擬似的に再現です。 そしてループ回数で何回やるかを決定します。

ちなみに、これよりかなり複雑なシナリオで 200 スレッドあげたら、クライアントのほうがへばりました。 ほどほどに(笑)

スレッドグループの子要素1。 クッキーマネージャ。

jmeter06

これをいれておくと cookie を食べてくれます。 まぁここではなくても動くですが、帯域なども測定したいときは入れておいた方がいいかもしれません。 また、認証があるときはこれをいれておくだけで、cookie 食べて次の HTTP リクエストで発行してくれます。

スレッドグループの子要素2。 実際にブラウザの代わりにアクセスしてくれるのが、HTTP アクセスです。

jmeter07

パスのところに注目で ${path} が入っています。 これが上ででてきた csv 項目を差し込んでいるところです。

あと、スクリーンショットきれてしまったのですが下にある「すべてのイメージとアプレットを繰り返しダウンロードする」にチェックをいれると、通常のブラウザと同様にイメタグとかのアクセスもしてくれます。

結果を表で、ツリーで表示は、いれておくと実行後の結果を格納してくれます。

では、

[tegaki]とりゃ、実行![/tegaki]

ここでは、仮想環境使わずにローカル->ローカルで自爆するようにしています。 なので、実行中に GUI のシステムモニタをみてみます。

jmeter10

うひょ~。 4コアの CPU 使っていますがいっぱいまであがっています。 メモリは平気そうですね。 普通は vmstat 1 とかのコマンドでみるといいかもです。

ちなみに、サーバサイドが Java/Tomcat の場合は JMeter からマネージャアプリの manager/status/xml にアクセスすることで Java のヒープとかグラフ化できる機能があります。 (トム5 とドキュメントにありましたが 6 でもいけました)

スレッドがすべて完了したら結果系をみてみます。

jmeter09

ツリーの方で、取得した HTML などがみれます。 シナリオがうまく動いていないときはこれをみるといいかもです。

表で表示では、http ステータスやアクセス時間や転送量などがみれます。

jmeter08

オールグリーンであることを見ながら、あや、10秒かかっちゃった人いるね、、みたいな。 HTTP のステータスコードがエラー系だと赤になりますので確認します。 🙂

一度シナリオができれば、Apache や MySQL のチューニングをしてアクセススピードの平均値をみたりできると思います。 ローカル、ローカルでやる場合はクライアント側でも負荷がかかりますのでできれば別マシンでやるほうがいいでしょう、

さて、こんなのつくっていくとコメントポストしてみたいなぁとか、管理画面を複数人で使ったらなどなどでてくるかと思います。(ないか(笑))

ここでは GET ばかりでしたが、JMeter は POST したり GET でもらってきた HTML を後処理、正規表現で hidden 値を変数にもらって次のリクエストで POST したりもできます。

ちょっと正規表現かくの大変ですが、wp_nonce とかもらってみたいな感じですね。 また、結果の HTML が正しい出力かどうかなどのアサートもすることができます。

というわけで、ぼくも 512M の VPS ぽい仮想環境をローカルにつくってやってみましょうか。 ちなみに、250M 付近の VPS で Apache + PHP はきついですねぇ。 動きますがちょっと負荷かけるとメモリ不足で Apache が飛んだ経験があります。 メモリ重要。:)

Atom でローカルサーバ更改(1)

うちにはコンピュータがたくさんあるため、ファイル共有や IMAP その他もろもろを集約するローカルサーバが一台たっています。

一度、電源が焼けてケース交換などはしたりしているのですが中身は何年も動き続けている働き者。 でもさすがに最近、ファンの音もおかしくなってきたりしていたので、リニューアルと相成りました。 🙂

せっかくなので趣向を変えてということで、CPU は省電力 Atom のものに決定。 ちょうどよく ギガバイ子ちゃんより、SATA * 4、IDE * 1 の使ってくれといわんばかりのマザーがでたのでこちらを選択しました。(普通の Atom マザーは SATA * 2 が多いす)

GA-D510UD (rev. 1.0) – ギガバイト – 製品情報 – マザーボード – 概要

Atom Dual-Core D510 (1.6GHz) がついて、9980 円。 マザー全体で二十数ワットしか使わないようです。 いままでのは Athron XP でしたが、性能上がって消費電力落ちちゃうのだから恐ろしいものです。

そしてこのマザー Mini-ITX。 これをサーバ用の ATX ケースに入れると、、、

IMG_0083

[tegaki]ちんまり(笑)[/tegaki]

なんででっかいケースにいれるかというと、ディスクがたくさんあるからなわけでで、今回は 1T *2 (RAID1) とシステム 250G を追加しています。

IMG_0082

いずれも SATA。 前は IDE の RAID 1 でしたのでこれも入れておきます。(それでこのマザーがぴったりだったのです)

マザーとメモリ(2G) と HDD とケーブルなど買って 32,000円ちょい。 いつも思いますが安くなったものです。

IMG_0084

ディスク 6 台フル実装の図。 🙂

というわけで、現在 CentOS 5.4 のインストール中。 懸念していた GIGABYTE SATA チップも、最新の CentOS のブートイメージを使うと難なく認識するようです。リリース当初の ISO では認識できないようなので、適当な ISO ブートイメージを焼いて riken.jp さんからFTP インストールしました。

さすがに 1T の RAID の構築は時間がかかります。。 これは待ち中に書いた記事であります。 続く。 😀

Jasper Reports で PDF ファイル出力

ちょっと必要がありまして、Jasper Reports というオープンソースの帳票出力ライブラリで PDF の出力を行いました。 使い方を忘れてしまいそうなのでメモがてら。 初めて使うライブラリは勝手が分からずなかなか大変です。 🙂

Jasper Reports とその帳票設計を行う iReport というアプリです。

jasperforge JasperReports Project Home

JasperReports is the world’s most popular open source reporting engine. It is entierly written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.

jasperforge iReport Project Home

iReport is the free, open source report designer for JasperReports. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.

Jasper Report は LGPL、iReport は AGPL です。 iReport のほうは NetBeans ベースでつくられているよう。 前者がライブラリで、後者がそのライブラリで読み込む GUI 帳票設計アプリケーションとなります。

とりあえず、ファイルをダウンロード。 以下二つを利用しました。 iReport のほうは、Linux、Mac OS X 版もあります。 Jasper Reports は pure java です。

jasperreports-3.7.1-project.tar.gz

iReport-3.7.1-windows-installer.exe

また、Jasper Reports の PDF 出力は iText PDF ライブラリに依存しています。 iText 自体は上記 project.tar.gz (のlib)に同梱されいますが、日本語の出力の際に必要な iTextAsian.jar が含まれていませんので以下からダウンロードします。(下の方です)

Browse iText, a JAVA-PDF library Files on SourceForge.net

extrajars  – ExtraJars1.0  – iTextAsian.jar

これでファイルの準備は完了。 iReport のほうは適当にセットアップしておきます。

Jasper Reports はいろいろなデータソースから帳票を出力できますが、今回は Java の Bean 経由で出力してみます。 DB に直つなぎとかもできるみたいですね。

最終的に Java からだすので、先にプログラムソースの準備を。

以下のようなモジュール構成にしておきます。 Jasper Reports の依存ライブラリがよく分かりませんでしたが、今回のプログラムで class not found がでなくなった最小構成としています。 また、先の iTextAsian.jar もいっしょに入れておきます。

Jasper01

templates フォルダには Jasper Repost の定義体を入れることにしましょう。

SampleReportBean.java が帳票に出力したいレコードを表現した Bean です。 Bean の内容は以下の通り。 getter、setter は省略。

   1: package net.maple4ever.jasper;
   2:  
   3: public class SampleReportBean {
   4:  
   5:     // メーカ
   6:     private String maker;
   7:     // 機種名
   8:     private String name;
   9:     // OS
  10:     private String os;
  11:     // CPU
  12:     private String cpu;
  13:     // メモリ容量
  14:     private String memory;
  15:     // ハードディスク容量
  16:     private String hdd;
  17:  
  18:     // 以下 getter/setter (省略)
  19: }

さてさて、ここから iReport の世界に入っていきます。 iReport 起動。

とりあえずオプション設定。 iTextAsian.jar と今ほどつくった Java プロジェクトに class path を通します。

 Jasper02

Eclipse で Java プロジェクトつくった場合は、プロジェクトロケーション/bin にします。(class ファイルできるところね) で、上のスクリーンショットでは忘れてしまっていますが、Relodable にチェックを入れます。 iTextAsian.jar にはチェックいらないでしょう。(Java プログラムを修正すると読み直してくれます)

了解おして、ここで iReport を一回再起動。(しないと iTextAsian が反映されませんでした)

でもってファイル –> NEW あたりから帳票新規作成。 ファイルの置き場所を先ほどの templates フォルダにします。 種類、ここでは A4 のブランクにしました。

Jasper03

Open this Template おして、

Jasper04 

みたいな感じです。

できたら、まずは帳票プロパティの Language を Java に変更します。 Groovy が標準のようですね。 これやらないと、後で Java から呼ぶときに groovy の class ないぞってエラーになります。

Jasper04-02

帳票設計画面はこんな感じです。

Jasper05

上から Title、Page Header、Column Header、Detail 1、Column Footer、Page Footer、Summary となっています。 この中で Detail の部分が繰り返しのデータをおくところになります。 ここが重要。

でもって、Title、Summary 部分が1ページと最終ページ。 Page/Column  Header、Footer が表ごとページごととなるようです。

ふまえて、レコードとなるさきほどの Bean を Detail 1 に配置していきます。 まずはデザイナ上部、Preview の横のデータベース矢印みたいなアイコンをクリックします。

Jasper05-02

さきほどつくった Bean のパッケージを入力して Read attributes を押下します。 さすると、Bean のプロパティがでてきます。 うまく読めないときは class path の設定を確認。

Jasper06

選択して Add Selected field(s) ボタンを押下します。 するとこのフィールドがデザイナ上で配置できるようになります。

画面左ツリーの Fields 木にいま追加したフィールド出現するので、ドラッグアンドドロップで Detail 1 に置いていきます。 罫線とか必要ならパレット開いて描画していきます。 static text とかでテーブルヘッダとかタイトルとかもつける。

日本語フォントは PDF Font name を「HeiseiKakuGo-W5」に、PDF Encording を「UniJIS-UCS2-H (Japanese)」にします。 こうしないと PDF になったときに日本語が出力されません。(Adobe Reader のフォント。ちょっと詳しくないですが、iTextAsian.jar の設定値なのかもしれません。 MSP ゴシックとかは設定できない模様)

まぁまぁこんな感じです。

 Jasper09

また繰り返しリストではなく、帳票全体でひとつの埋め込み項目は「パラメータ」として配置することができます。 左ツリーのparameter で追加して名前をつけて置いていきます。

Jasper08

でもって、なんとなくできたらデータを埋め込んでみます。 iReport には任意の Java を呼び出してその帰り値の Collection を埋め込んでくれる便利な機能がありました。(Biz Stream はこれできないよね?)

とりあえずさきほどの Java のプロジェクトに SampleReportFactory.java というソースを追加しました。 createBeanCollection という static なメソッドが標準で使われるようなのでこれも用意しておきます。 こんな感じです。

   1: public class SampleReportFactory {
   2:     
   3:     public static List<SampleReportBean> createBeanCollection() {
   4:         
   5:         List<SampleReportBean> lines =
   6:             new ArrayList<SampleReportBean>();
   7:         
   8:         for(int i=1; i<100;i++) {
   9:             SampleReportBean line = new SampleReportBean();
  10:             line.setName("自作機2号");
  11:             line.setMaker("ひろまさ");
  12:             line.setOs("Ubuntu 9.10");
  13:             line.setCpu("PhenomII X4");
  14:             line.setHdd("320GByte");
  15:             line.setMemory("4GByte");
  16:             line.setColor(String.valueOf(i % 2));
  17:             lines.add(line);
  18:         }
  19:         return lines;
  20:     }
  21: }

iReport に戻って画面上部のデータソースのアイコンを押下します。

Jasper05-01

JavaBeans set datasource を選択。

 Jasper10

でもっていまつくった SampleReportFactory を指定します。

Jasper11

Test おして OK もらったら Save します。

で、デザイナの Preview を押してみると帳票につくったデータソースがバインドされた結果が表示されます。 🙂

Jasper13

ソースコードから入力をつくれるので桁数試験とか結構便利です。

さてさて、ちゃんとした帳票だと罫線の制御とかしたくなることがあります。

ちょっとマニュアル調べて簡単そうだったのが各描画オブジェクトがもつ、Print When Express というプロパティ。 フィールドとかの値を判定して表示の可否をきめることができます。

たとえば、行をしましまにしたかったら Bean にそれっぽいフラグ項目をつくって、

Jasper14

こんな感じで Print When Expression を設定してあげると true のときだけ表示になります。(Jasper への戻値は、boolean じゃなくて Boolean のようなので注意してください)

というわけで灰色ざぶとんを行の下に敷いて、しましま。 とか。

Jasper15

他にも良い方法があるとは思うですが、これさえあればあとは組み合わせ、、知恵と勇気でなんでもいけるかと。。(笑)

では最後に Java から作った帳票をだしてみます。 iReport 終了。 iReport で保存・コンパイルされたものが templates フォルダに入っているはずです。

Jasper16 

.jasper がコンパイルされた結果です。 プログラムからはこちらを使います。(動的コンパイルもできるみたいですがここでは割愛)

面倒なので先ほどの SampleReportFactory クラスに main を追加する感じで。 List はさきほどつくったもの。 また、HashMap にパラメータを設定して Jasper に渡すと PDF ができる感じです。

   1: public class SampleReportFactory {
   2:  
   3:     // さきほどの createBeanCollection メソッド省略
   4:  
   5:     public static void main(String args[]) throws JRException {
   6:         
   7:         // 出力するBean のつまった List を DataSource に設定
   8:         JRBeanCollectionDataSource ds =
   9:             new JRBeanCollectionDataSource(
  10:                 SampleReportFactory.createBeanCollection());
  11:         // パラメータの Map 作成
  12:         Map<String,String> param = new HashMap<String,String>();
  13:         param.put("now", "2010/03/11");
  14:         // これらのデータを元に PDF 作成
  15:         JasperPrint pdf = JasperFillManager.fillReport(
  16:                 "./templates/sample-report.jasper", param, ds);
  17:         // PDF をファイルとして出力
  18:         JasperExportManager.exportReportToPdfFile(pdf,
  19:                 "./templates/sample-report.pdf");
  20:         
  21:         // pdf.addPage((JRPrintPage)pdf.getPages().get(0));
  22:         
  23:     }
  24:  
  25: }

実行~。

Jasper17

おめでとうございます(笑)

最後のサンプルソースの一番下にコメントでかいてありますが、複数のテンプレートをつなげて一つの PDF にすることもできそうです。

   1: // pdf.addPage((JRPrintPage)pdf.getPages().get(0));

addPage の引数に index ありもあったので、交互差し込みとかもできるかもですね。

ここまできたら、本家のマニュアルの xml タグを調べていけばあとはなんとか。。(笑)

JasperReports 3.7.1 – Schema Reference

This document describes the structure of the JRXML report template files for the JasperReports library.

Expression 系でいろいろできそうです。

以上、参考になりましたら。