HTTPの最近のブログ記事

分散コンポーネントを作成する場合、どのくらいの粒度でインタフェースを定義すればいいのかということについては、一般的な基準や指標というものはありません。アプリケーションの特性から、個々に判断するしかありません。
最近、Ajaxの普及により、クライアントからサーバ側にあるコンポーネントを、気軽に呼び出す処理が増えてきています。例えば、HTMLフォームのテキストフィールドに、顧客IDが入力されたら、サーバの顧客コンポーネントを呼び出して、対応する顧客名を取得して表示するといったような処理で使用されます。
こういった単発的かつ単純な処理であれば、多くの場合、それほど気にする必要はないかもしれません。ただし、サーバ側コンポーネントで複雑なビジネスロジックを実行していたり、ある程度まとまった量のデータを取得するような場合は、パフォーマンスの問題に遭遇することがあります。冒頭で述べた通り、どこにでも通用する基準や指標はないですが、どのようなことに気をつければいいかについて、考えてみたいと思います。

不適切な再利用に注意する。

サーバ内部で使用されることを想定したコンポーネントのインタフェースを、そのままクライアントに公開し、「再利用」させてしまう場合には、パフォーマンスの問題が起こりえます。例えば、顧客IDを渡せば、該当する顧客の属性情報(名前、住所、勤務先など。。。)をDBから取得する「顧客情報取得共通処理」と命名されたインタフェースがすでにあるとします。このような類のものは、サーバ側では、多くの箇所で「再利用」され、有用性の高いインタフェースです。 Ajaxクライアント側から見た場合はどうでしょうか?前述のように、単に顧客名を表示する目的であれば、ほとんどが不要なデータである可能性が高いですね。 すでにあるからという理由で無理に「再利用」せず、Ajaxクライアント向けに必要なものだけにしぼった小さいサイズのデータを返すインタフェースを用意しましょう。

呼び出し回数が多くなりすぎないようにする

インタフェースの粒度が小さすぎると、クライアント-サーバ間の通信回数が多くなります。ネットワーク通信には、どうしてもオーバヘッドがあるので、回数多いことがボトルネックの要因になることがあります。解決策は、EJBでよく使われる、「Data Transfer Objectパターン」的に、適切な粒度にまとめることです。 例えば、当たり前のことですが、1つの商品IDに対する商品名取得処理と商品単価取得処理は、1つのインタフェースに統合すべきであることが多いです。複数件のデータ取得を行うことがわかっている場合も、1回の呼び出しで必要な件数のデータが取れるようにしたほうがいいでしょう。

結局のところは、その場の判断で、ちょうどいいところを見つけることが重要です。 もしも、Ajaxに関するパフォーマンスの問題にぶつかった場合、ここで挙げたようなことも、確認してみてください。ソースから発見することはむずかしいかもしれませんが、そのときには、「Webアプリケーションとネットワークのモニタリング」にて紹介した方法で見つけることができます。また、他のメンバーの「パフォーマンスを意識したAjaxのご利用を」にも関連する情報があるので、参考になると思います。

Webアプリケーションのレスポンスタイムがよくない場合、問題を解析するにあたり、以下のようなことをやってみたりすると思います。
  • ストップウォッチで、submitしてから画面表示動作が完了するまでの時間を測定する。
  • サーバ上のログ(HTTPアクセスログ、アプリケーションが出力するログなど)を見る。
ここで、0.5秒で終るはずのサーバ側アプリケーションの処理が、10秒かかっていることがわかった場合は、そのときのWebアプリケーションサーバや、DBサーバの状態など、サーバ側を調査するという流れになると思います。
ところが、サーバアプリケーションの処理は、0.5秒で完了しているのに、ブラウザへの表示処理が終るまでには10秒以上かかるということになると、話はちょっと違ってきます。 こういったケースでの、次なる一手はどうすべきでしょうか?

インターネット接続の場合は、ネットワークトラフィックの問題に起因することも考えられますが、LANで接続されている場合には、また別のところにボトルネックが潜んでいる可能性が高くなります。 最近は、Ajaxを使ったRichクライアント型のアプリケーションが増えてきていますが、そこで実装されるJavaScriptのコーディングやHTML文書の構造も複雑化しており、パフォーマンスに与えるインパクトが無視できないものになっています。

そういったときに、問題を切り分けるための手段の一つとして、ネットワークモニタリングが有効です。取得されるデータには、タイムスタンプが記録されるため、クライアントからリクエストが送信され、サーバからレスポンスを受信するまでの時間を正確に知ることができ、ボトルネック箇所を絞り込みやすくなります。このときに、サーバとクライアントの時刻を合わせておくことが肝心です。 Webアプリケーションの場合には、以下に示す2つのレベルのモニタリングがあります。
  • HTTPレベルのモニタリング
    デバッグ用のHTTP Proxyを使って、HTTP リクエスト/レスポンス電文をキャプチャリングする。キャプチャリングデータには、余分な制御電文などは含まれず、HTTP電文として、見やすいフォーマットに編集して表示してくれる。
    但し、ブラウザのProxy設定を変更する必要があるので、それをしたくない人には不向きである。
  • TCP/IPレベルのモニタリング
    HTTPレベルでは問題が検知できない場合には、ネットワーク上を流れるパケットの単位でキャプチャリングする機能を持ったソフトウェア(Snifferとも呼ばれる)が必要になる。一般的なキャプチャリングソフトは、デフォルトでは、すべてのパケットをキャプチャリングしてしまうので、対象を必要なものだけに絞り込むためのフィルタリング機能が用意されている。
    NICをターゲットにしてキャプチャリングを行うため、クライアントとサーバが同一ホスト内で稼働している場合には適用できない。

パフォーマンスの問題などを、外見だけで調査しようとしても限界がありますし、視点を変えて解析してみることで、今まで見えなかったものが見えてくる場合もあります。
もしも、興味がある方は、とりあえず自分が開発しているWebアプリケーションで、どんな情報が流れているのか、モニタリングしてみてください。まず、問題発生時の状態と比較するために、正常時にどうなっているかを把握しておくことは大事ですし、見ること自体がHTTPやTCP/IPの勉強にもなると思います。

ご参考までに、以下に、Windows環境で利用可能なソフトウェアを挙げておきます。