Powered by SmartDoc
JAPANESEENGLISH

Jawprofドキュメント

目次

イントロダクション

概要

Jawprof(Java Application Workload Profiling Framework)はJavaアプリケーションのワークロードプロファイリングを行うためのフレームワークです。ワークロード(workload)とは、システムに加わるユーザからの負荷の総称です。システム性能評価の第一歩は、このワークロードを定量的に知ることです。Jawprofはこのワークロードを簡単に測定するための手段を提供することを目的としています。[2]。ワークロードプロファイルには以下の情報が含まれます。

Javaアプリケーション用の負荷検証用のツールとしてJakarta JMeterがあります。このようなソフトウェアはアプリケーションがパフォーマンス要件を満たしているかを検証するために使うことができます。また、パフォーマンス上のホットスポットとなっている部分を探すためのプロファイリングツールも多くのプロダクトがフリーソフトウェアも含めあります。

一方、アプリケーション開発プロジェクトでは要件定義の一部としてパフォーマンス要件を定義することとなります。このパフォーマンス要件の定義は、当然パフォーマンスの基準を定量化することになるわけですが、満たされるべきパフォーマンス要件をアプリケーションの開発の前に決定すること(決断してもらうこと)は困難である場合がほとんどです。そこで、アプリケーション稼動後に実際の運用状況を確認した後、パフォーマンス要件を定義し、その目標までチューニングを行うこともあります。

このパフォーマンス要件の定義を行う根拠となるデータを収集するために、時間帯ごとのCPUやディスクの負荷状況を調べることは可能ですが、アプリケーションのレベルでの情報、例えばのべ何人がアクセスし、商品の検索を実施したのが何人で、購入手続きを行ったのが何人かなど、はアプリケーションレベルで収集するしかありません(2)

また、稼動後もアプリケーションの視点でどの程度アクセスがあるか、どの時間帯に処理が集中するか、どの処理が多く使用されるのか、何曜日に処理が集中するかなどの情報を元にシステムの保守や改良点の検討が可能になります。

  1. ここで言うトランザクションとはただの「処理」という意味で、「処理のまとまり」としての意味はありません。また、Jawprofは後者の意味でのトランザクションを自ら認識したりすることはできません。
  2. アプリケーションによっては発行されたSQLなどから導出できるかもしれませんが、その労力は大変なものです。

特徴

Jawprofは次の目的をサポートします。

トランザクションプロファイル
  • 発生したトランザクションの種類を記録する。
  • 発生したトランザクションの発生時間を記録する。
    シングルプロファイル
  • 各々のトランザクションの処理時間を測定する。
  • 各々のトランザクションの任意のポイントの通過時間(ラップタイム)を測定する。
  • 各々のトランザクションの種類を記録する。
  • モニタリングを開始するときは、モニタIDを指定する必要があります。モニタIDは同時に利用されているモニタを区別するためのものです。セッションオブジェクトを利用することが可能です。

    トランザクションにはIDが付与されます。これはJawprof側で付加するもので、呼び出し側が意識する必要はありません。

    JAMon との違い

    Jawprofに似ているフレームワークとしてJAMon[1]があります。Jawprofは多くのアイディアをJAMonから得ています。Jawprofに関心のあるプログラマはJAMonも調査するべきです。

    JawprofとJAMonには以下の違いがあります(3)

    最後にありますが、Jawprofは集計したりする機能は一切持ち合わせていません。この作業は外部の表計算ソフトや分析ソフトに委ねられる事を想定しています。

    1. 作者がJAMonに感じた不満と言ったほうが適切かも知れません。また、JAMonの機能を作者が勘違いしている可能性もあります。

    チュートリアル

    インストール

    JawprofとJawprofが利用しているパッケージとの関係を図2.1.1[Jawprof と関係パッケージ]に示します。

    Jawprof と関係パッケージ

    Jawprofはこれらのパッケージに依存しています。従って、これらのパッケージを全てインストールする必要があります。以下に必要なパッケージをまとめます。まだ、これらのパッケージを持っていなければ、ダウンロードするなどして、取得してください。

    依存パッケージ
    パッケージ名 URL 必須
    Jakarta Commons Logging http://jakarta.apache.org/commons/logging/
    Log4J http://logging.apache.org/log4j/docs/
    Jakarta Commons Collections http://jakarta.apache.org/commons/collections/
    Jakarta Commons Pool http://jakarta.apache.org/commons/pool/
    Jakarta Commons DBCP http://jakarta.apache.org/commons/dbcp/

    JawprofはアプリケーションからJawprofのAPIを呼ぶことによって利用します。従って、開発しているアプリケーションのコンパイル時にクラスパスが通っている所へjawprof.jarを置きます。これで、JawprofをあなたのアプリケーションにJawprofを利用した機能を追加する準備は完了です。

    アプリケーションで使用する

    Jawprofの動作設定は"jawprof.properties"ファイルで行います。また、Jakarta Commons LoggingおよびLog4J(4)にもそれぞれ、"commons-logging.properties"および"log4j.properties"が必要ですから、これらのファイルをクラスパスの通っているディレクトリに移動します。

    1. Commons Loggingの実装ロガーとしてLog4Jを利用する場合

    GUI ツールの準備をする

    JawprofにはシンプルなGUIツールが付属しています.このツールはデータベースに登録されているワークロード情報を確認するためのものです.

    Jawprof GUI ツール

    デフォルトの設定では「Technical Articles and Tips Java look and feel Graphics Repository」にあるアーカイブを利用するようになっています.ダウンロードしてクラスパスを通して使用してください.

    API の使用方法

    APIの詳細についてはJawprof API 仕様を参照してください。

    簡単な例

    トランザクションの記録は全てモニタを通して行われます。jawprof.Monitor.start()が呼ばれるとモニタリングが開始され、jawprof.Monitor.stop()が呼ばれると、モニタは管理下から外れます。

    リスト2.2.1.1[最初の例]を見てください。Monitor m = MonitorFactory.getMonitor("SAMPLE");でモニタを獲得しています。引数のSAMPLEがモニタIDです。この時点ではモニタリングは開始されていません。次のm.start();によりモニタリングが開始されます。モニタはstart()メソッドが呼ばれると、呼ばれた時点の時刻をトランザクションが開始された時刻として記録します。stop()メソッドが呼ばれるとモニタはモニタリングの結果を記録する手続きを行います。

    トランザクション種別はいつでも設定可能です。従って、jawprof.Monitor.start()を呼ぶ時点では結果的にそのトランザクションの種別が不明でも問題ありません。jawprof.Monitor.stop()を呼ぶ前に、jawprof.Monitor.setType(Object)を呼びトランザクション種別を設定することが可能です。

    モニタリング中にラップタイムを得ることも可能です。ラップタイムを得るにはjawprof.Monitor.lap(Object)メソッドを使用します。引数はラップタイムのIDです。

    最初の例
    import jawprof.*;
    
    public class Example1 {
    
    	public static void main(String[] args) {
    
    		Monitor m = MonitorFactory.getMonitor("SAMPLE");
    		m.setType("TYPE");
    		m.start();
    		m.lap("LAP0");
    		m.lap("LAP1");
    		m.stop();
    
    	}
    
    }
    

    実行する前に設定ファイルを準備する必要があります。出力先などの設定はjawprof.propertiesファイルで行います。(5)

    jawprof.propertiesファイルには全体の設定を取り扱うコンテキストクラスの設定をjawprof.context要素で行います。通常はデフォルトの設定のjawprof.DefaultJawprofContextで問題ないでしょう。

    トランザクションプロファイリングの結果はRecorderと呼ばれるクラスにより記録されます.標準出力、CSVファイルなどのファイルへの出力、データベースへの出力がサポートされています。必要により独自のRecorderを準備することも可能です。使用するRecorderのFactoryをjawprof.recorder.factoryにて設定します。まずは標準出力に出力するjawprof.SimpleRecorderのFactoryであるjawprof.SimpleRecorderFactoryを使用します。

    jawprof.SimpleRecorderは内部ではjawprof.FormatRecorderの一種として定義されています。jawprof.FormatRecorderは指定されたフォーマットでモニタリングの記録を出力先へ記録します。まずはリスト2.2.1.2[設定ファイル]のように設定してください。

    設定ファイル
    # JawprofContext
    jawprof.context=jawprof.DefaultJawprofContext
    jawprof.recorder.factory=jawprof.SimpleRecorderFactory
    jawprof.recorder.formatrecorder.format.start={0},{1},{2},START,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.stop={0},{1},{2},STOP,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.lap={0},{1},{2},{4},{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    
    1. パッケージに設定ファイルは含まれています。必要に応じてコメントアウトするなど編集して使用してください。

    jawprof.jarjawprof.propertiesにクラスパスを通し、コンパイルおよび実行するとリスト2.2.3[出力例]の様に出力されます。

    出力例
    10901318-0,SAMPLE,TYPE,START,2004/07/18:15:24:43:070
    10901318-0,SAMPLE,TYPE,STOP,2004/07/18:15:24:43:080
    10901318-0,SAMPLE,TYPE,LAP1,2004/07/18:15:24:43:080
    10901318-0,SAMPLE,TYPE,LAP0,2004/07/18:15:24:43:070
    

    一つのトランザクション種別は、任意の数のトランザクショングループに所属できます。

    保存先の変更

    CSV ファイルへ保存する

    CSVファイルに出力するにはRecorderとしてjawprof.FileRecorderを使用します。jawprof.FileRecorderjawprof.FormatRecorderの一種として定義されています。リスト2.3.1.1[CSV ファイルへの出力設定]の用にフォーマットと出力ファイルを設定します。

    CSV ファイルへの出力設定
    jawprof.context=jawprof.DefaultJawprofContext
    jawprof.recorder.factory=jawprof.FileRecorderFactory
    jawprof.recorder.formatrecorder.format.start={0},{1},{2},START,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.stop={0},{1},{2},STOP,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.lap={0},{1},{2},{4},{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.filerecorder.file.start=tran.csv
    jawprof.recorder.filerecorder.file.stop=tran.csv
    jawprof.recorder.filerecorder.file.lap=tran.csv
    

    Jakarta Commons Loggings ロギングライブラリを使って保存する

    Jakarta Commons Loggingsを使用して出力することも可能です。jawprof.recorder.factoryjawprof.CommonsLoggingRecorderFactoryを設定し、Jakarta Commons Loggingsの設定を行います。Jakarta Commons Loggingsの設定についてはJakarta Commons Loggingsのドキュメントを参照してください。

    データベースへ保存する

    データベースへ保存することも可能です。データベースへ保存する場合はjawprof.recorder.factoryjawprof.DatabaseRecorderFactoryを設定し、データベースへの接続情報を設定します。jawprof.propertiesの内容はリスト2.3.3.1[データベースへの出力設定]の用になります。

    データベースへの出力設定
    jawprof.context=jawprof.DefaultJawprofContext
    jawprof.recorder.factory=jawprof.DatabaseRecorderFactory
    jawprof.recorder.databaserecorder.driver=org.gjt.mm.mysql.Driver
    jawprof.recorder.databaserecorder.url=jdbc:mysql:///jawprof?useUnicode=true&characterEncoding=SJIS
    jawprof.recorder.databaserecorder.user=user_name
    jawprof.recorder.databaserecorder.password=user_password
    

    その上で、データベースの準備を行う必要があります(6)。データベースの構造を図2.3.3.1[ER 図]に示します。

    ER 図

    各テーブルの定義は次のようになっています。

    トランザクションテーブル
    項目名 長さ 少数 必須 主キー
    ID VARCHAR2 32 - Y 1
    START_TIME TIMESTAMP - - Y
    START_TIME_MILLIS NUMBER 3 0 Y
    STOP_TIME TIMESTAMP - - Y
    STOP_TIME_MILLIS NUMBER 3 0 Y
    TYPE VARCHAR2 16 Y
    ラップテーブル
    項目名 長さ 少数 必須 主キー
    TRANSACTION VARCHAR2 32 - Y 1
    ID VARCHAR2 32 - Y 2
    TIME TIMESTAMP - - Y
    TIME_MILLIS NUMBER 3 0 Y
    トランザクショングループテーブル
    項目名 長さ 少数 必須 主キー
    ID VARCHAR2 16 - Y 1
    トランザクショングループマップテーブル
    項目名 長さ 少数 必須 主キー
    TYPE VARCHAR2 16 - Y 1
    GROUP VARCHAR2 16 - Y 2
    1. パッケージに必要なDDL文は含まれています。

    非同期に複数の記録先へ記録する

    非同期に記録するためにはTimerTaskRecorderを使用します。また、標準出力とデータベースなど複数の出力先へ記録するにはMultiRecorderを使用します。

    これらを使用して標準出力とデータベースに出力する設定例をに示します。

    非同期複数の記録
    jawprof.context=jawprof.DefaultJawprofContext
    jawprof.recorder.factory=jawprof.TimerTaskRecorderFactory
    jawprof.recorder.formatrecorder.format.start={0},{1},{2},START,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.stop={0},{1},{2},STOP,{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.formatrecorder.format.lap={0},{1},{2},{4},{3,date,yyyy/MM/dd:HH:mm:ss:SSS}
    jawprof.recorder.databaserecorder.driver=org.gjt.mm.mysql.Driver
    jawprof.recorder.databaserecorder.url=jdbc:mysql:///jawprof?useUnicode=true&characterEncoding=SJIS
    jawprof.recorder.databaserecorder.user=user_name
    jawprof.recorder.databaserecorder.password=user_password
    jawprof.recorder.multirecorder.member=jawprof.SimpleRecorderFactory,jawprof.DatabaseRecorderFactory
    jawprof.recorder.timertaskrecorder.factory=jawprof.MultiRecorderFactory
    jawprof.recorder.timertaskrecorder.interval=1000
    

    ケーススタディ

    シングルプロファイ

    トランザクションプロファイル

    トランザクションプロファイルとして以下のようなことができます。

    SQLで集計されます。スナップショットを登録し、月末や週末に更新します。EXCELでは可能か?

    レポートの作成

    拡張方法

    アーキテクチャと拡張

    基本アーキテクチャ

    Jawprofのクラス図を図3.1.1[Jawprof 基本クラス]に示す。

    Jawprof 基本クラス

    MonitorFactoryクラスはSingletonオブジェクトです。Monitorオブジェクトの生成/消滅を管理します。MonitorFactoryは測定した結果をRecorderオブジェクトを使用して保存します。クライアントは、getMonitor()メソッドを使用してMonitorオブジェクトを獲得します。この時、Monitor IDを引数として渡す必要があります。このIDは今測定中のMonitorを一意に識別するためのIDで測定期間全てに渡って一意なIDをクライアントが提供する必要はありません。モニタが要求されると、MonitorFactoryはトランザクションシリアルナンバーを生成します。このシリアルナンバーはSystem.currentTimeMillis() / 100000 + "-" + "シーケンス番号"で生成されます。例えば10792179-1, 10792179-2,...です。

    TransactionRecordは状態を持ちます。状態は「モニタリング中(Monitoring)」と「保存中(Saving)」です。タイムアウトすると記録から消えます。MonitorはTransactionRecordの状態ごとに管理します。モニタリング中はHashMapで管理し、保存中はリストで管理します。保存中のTransactionRecordは同期/非同期に保存されます。各トランザクションレコードはキーで識別される。モニタリング中のトランザクションが重複しなければよい。

    シーケンス図

    出力

    出力はjawprof.Recorderの実装クラスが行います。予め、jawprof.FileRecorderとjawprof.DatabaseRecorderの2つのabstractクラスが作成されています。jawprof.FileRecorderは任意の区切り文字で、出力を行います。JawprofではCSV形式での出力を予めサポートしています。jawprof.DatabaseRecorderはリレーショナルデータベースへの出力を行うjawprof.Recorderの実装クラスを作成するための抽象クラスです。

    更新の制御は、デーモンスレッドを利用したタイマーで行われます。

    の組み合わせで更新します。具体的には、JDBC接続ではjava.sql.PreparedStatement.addBatch()を使って一度に複数のレコードを登録します。

    出力先の切替

    CSV ファイル出力

    トランザクションの開始時刻、終了時刻、各ラップタイムをそれぞれ1レコードとして出力します。出力レイアウトは"<トランザクションID> <モニタID> <ラップID> <時刻>"です。開始時刻、終了時刻のラップIDは"START"と"STOP"です。時刻は"yyyy/MM/dd:HH:mm:ss"の形式で出力されます。例えば

    10792509-994,994,START,2004/03/14:16:55:49
    

    デフォルトのコンソール出力でも同様です。ただし、","がスペースに変わります。

    データベース出力

    Jawprofはそれ自身でコネクションプーリングを行いません。

    データベースへのトランザクション記録の保存期間を設定することが可能です。これは定期的あるいはトリガーによって起動され、保存期間より前のレコードは削除されます。

    ロギングライブラリ出力

    参考文献

    [1]Steve Souza. JAMon(Java Application Monitor) Users Guide. http://www.jamonapi.com/,
    [2]亀田寿夫、紀一誠、李頡. 性能評価の基礎と応用. 共立出版, 1998.
    [3]http://e-words.jp/. IT 用語辞典 e-words. 株式会社インセプト,


    SourceForge.jp