現場から学ぶWebアプリ開発のトラブルハック 第12回
アプリ開発でも、よ〜く考えよう。
キャッシュは大事だよ
佐藤聖規
2008/10/15
本連載は、現場でのエンジニアの経験から得られた、APサーバをベースとしたWebアプリ開発における注意点やノウハウについて解説するハック集である。現在起きているトラブルの解決や、今後の開発の参考として大いに活用していただきたい(編集部) 。
“無駄”より“遅い”ものはない
今回の主な内容 |
ではなく使うもの |
今回もパフォーマンスにまつわるトラブルをハックするが、アプリケーションのパフォーマンスチューニングで最も有効な手段は「処理を行わない」ことである。何もしないことに勝る高速化は存在しない。今回のトラブルでは、インスタンスをキャッシュ化して、無駄な処理を行わないことでチューニングを行う手法を紹介する。
しかしながら、往々にしてチューニングはトレードオフである。そのトレードオフが引き起こす、さらなるトラブルを紹介する。
■ コンサルティングもトラブルハッカーの仕事
とあるプロジェクトから1通のメールが届く。
「あるJavaで作成したリッチアプリケーションのパフォーマンスに問題を抱えている。自分たちで考えられ得る対策は講じた。しかし、目標のパフォーマンスを達成できない」とのことで、相談に乗ってほしいそうた。
こういったケースをメールでやりとりしても“らち”が明かないため、早速現場へ急行する。トラブルが発生した場合に何をするべきなのか、が分からないプロジェクトは多い。そんなプロジェクトのコンサルティングを行い、進むべき道を示すのもトラブルハッカーの仕事である。
■ まさかXMLが
早速現場の担当者にヒアリングを行う。今回パフォーマンスが出ていないシステムはJavaリッチアプリケーションであり、サーバとクライアントの間の通信をXMLで行っている(図1)。
![]() |
| 図1 システム構成 |
また、これまでの調査では、サーバ側の処理はさほど速度が遅くはなく、クライアント側の処理がボトルネックになっているとのことであった。
SOAPに代表されるXMLを用いて通信を行うシステムでは、XML操作に関する以下の処理がボトルネックになりやすい。
- XMLのパース
- XMLとJavaオブジェクトのマッピング
XMLの取り扱いには苦い思い出があるため、真っ先に担当者へ確認をしたがXMLに関しては「すでに以下のようなチューニングを施した」と伝えられた。
- XML入れ子構造の簡略化
- 操作差分分のXMLだけを送信するように修正
先入観は判断を鈍らせる
先入観を持つと視野が狭くなって、問題の本質を見失ってしまう。再び冷静になり事態を整理する。
- GCの頻度はさほど高くない
- 通信が発生する操作を行うとCPU利用率が急上昇する
以上から、本連載第1回「Webアプリの問題点を「見える化」する7つ道具」のトラブル切り分けフローに基づき、メソッドプロファイラの導入を決定して、処理時間がかかっているメソッドを特定することにした。
■ プロファイラは、何でもお見通し
早速、フローの手順3「メソッドプロファイリング」に基づき、あるメソッドプロファイラをアプリケーションにアタッチして、どのメソッドがボトルネックなのかを確認した。
また、結果を平均化するため通信を行う操作を10回繰り返したときの結果をプロファイリングした。プロファイリングの結果は図2のとおりである。
![]() |
| 図2 プロファイリングの結果(一部を再現したものです)(画像をクリックすると拡大します) |
一見すると、普通のプロファイリング結果であるが、よく見てみると大きな問題に気が付く。
そう、「getInitBillingProps」メソッドの呼び出し回数が実行回数の10回と一致しているのだ(図2の赤枠参照)。
名前から推測するにアプリケーション初期化のためにプロパティファイルのロードを行い、プロパティの値をインスタンス化しているようである。メソッドの名前どおりの動作を行っているとすれば、アプリケーションの通信の操作を10回繰り返したからといって、「getInitBillingProps」メソッドが10回実行されるのは明らかにおかしいはずである。
■ 「getInitBillingProps」メソッドの挙動を確認
まずは、ソースを確認する。やはりプロパティファイルからプロパティの値をオブジェクト化しているだけである。念のため、忙しそうにしている担当者を捕まえて、メソッドの仕様の確認をした。やはり「getInitBillingProps」メソッドはアプリケーションの初期化のためにプロパティの値をインスタンス化するためのメソッドらしい。
![]() |
| 図3 通信時の挙動 |
すなわち、このアプリケーションは通信を行うごとにプロパティファイルにアクセスしていることになる。つまるところ、完全に無駄な処理を行うのである。これでは、パフォーマンスが出るはずもない。
では、こういった状況ではどのような解決策があるのか? 読者の皆さんも考えてみてほしい。次ページで、その回答例を提示しよう。
1-2 |
| Index | |
| 第12回 アプリ開発でも、よ〜く考えよう。キャッシュは大事だよ | |
| Page1 無駄”より“遅い”ものはない 先入観は判断を鈍らせる |
|
| Page2 キャッシュは、ためるものではなく使うもの 過ぎたるは及ばざるがごとし 怠惰(Lazy)に問題を解消 ご利用は計画的に |
|
現場から学ぶWebアプリ開発のトラブルハック バックナンバー 連載インデックスへ»
- 第1回 Webアプリの問題点を「見える化」する7つ道具
- 第2回 “Stop the World”を防ぐコンカレントGCとは?
- 第3回 【実録ドキュメント】そのログ本当に必要ですか?
- 第4回 DBアクセスのトラブルは終盤で発覚しがち……
- 第5回 OutOfMemoryエラー発生!? GCがあるのに、なぜ?
- 第6回 【真夏の夜のミステリー】Tomcatを殺したのは誰だ?
- 第7回 【トラブル大捜査線】失われたコネクションを追え!
- 第8回 肥え続けるTomcatと胃を痛めるトラブルハッカー
- 第9回 JavaのGC頻度に惑わされた年末年始の苦いメモリ
- 第10回 ThreadとHashMapに潜む無限回廊は実に面白い?
- 第11回 スレッドダンプの森で覚えた死のロックへの違和感
- 第12回 アプリ開発でも、よ〜く考えよう。キャッシュは大事だよ
- 第13回 DB操作の“壁”を壊すJPAが起こした「赤壁の戦い」
- 第14回 数百キロのコードでブルー - ドクターTomcat緊急救命
| Java Solution全記事一覧 |
- あなたの知らない、4つのマニアックなJava文法 (2010/7/27)
ネストした型を深く活用するために、staticのネストしたクラス、内部クラス、隠蔽、無名クラス、ローカル内部クラスなどを解説 - 内部統制に効く! ID管理・シングルサインオンの常識 (2010/7/16)
ID管理や認証、シングルサインオンの概要を解説し、Java標準のJAASを紹介し、JBoss SSOでサンプルを作成します - 設計者/SEが覚えておきたいJavaと.NETの違い (2010/7/6)
GUI開発のクライアントサイド技術やユーザー配布技術、RIA、Webアプリ開発のサーバサイド技術、データアクセスについて基本から整理します - 開発者が知っておきたいAndroid 2.2新機能 12連発 (2010/7/1)
先日ソースコードが公開されたFroyoの新機能を紹介します。Flash PlayerやJITコンパイラ、マルチタッチのサポートなど
|
|
スキルアップ/キャリアアップ(JOB@IT)
スポンサーからのお知らせ
- - PR -
- - PR -
お勧め求人情報












