連載
» 2011年06月24日 00時00分 公開

Tomcat 7の新機能で何ができるようになるのか?(3):技術者が知っておきたいTomcat 7の新機能20連発 (1/3)

[藤野圭一,NTT OSSセンタ]

Servlet 3.0実装以外のTomcat 7の新機能とは

 連載第1・2回の「Tomcat 7も対応したServlet 3.0の6つの主な変更点」でTomcat 7の紹介としてServlet 3.0に関する機能について説明しました。今回はServlet仕様のアップデート以外によるTomcat 7の新機能について紹介していきます。

 Tomcat 7の変更点の全てがServlet 3.0によるものではありません。Webアプリケーションのバージョン管理機能やメモリリーク防止と検知機能、エイリアス(alias)サポート、Tomcatをプログラムに組み込むための軽量APIの提供など、Tomcat 7ではServlet仕様のアップデート以外にも、さまざまな新機能の追加やコードの改善を行っています。

 今回は、その新機能のうち、20個を厳選して紹介していきます。

  1. Webアプリのバージョン管理「Parallel deployment」
  2. メモリリークの可能性があるクラスを初期化
  3. さまざまな参照をクリアしてメモリリーク防止
  4. メモリリークの探知機能「Find leaks」
  5. さまざまなTomcatの実行方法が追加
  6. Apacheと同様なエイリアス(aliases)をサポート
  7. JNDIリソースのクローズ処理サポート
  8. コネクタ実装の統一
  9. CSRFを防止するフィルタ
  10. Tomcat版「mod_expires」でキャッシュの有効利用
  11. 長時間処理しているリクエストを検知
  12. Webクローラによるセッション大量生成を防止
  13. 仮想クラスローダ機能
  14. Tomcatのロギング機能に新クラスが追加
  15. ライフサイクルアーキテクチャの変更
  16. アクセスログの機能追加
  17. セッション固定攻撃対策
  18. セッションアクセス時間の仕様準拠
  19. ValveからFilterへの移行
  20. 「META-INF/context.xml」のコピー

7になっても変わっていないところ

 まずは、Tomcat 7の新機能を見る前に、今までと変わっていないところも多く存在しますので、簡単に紹介していきます。

ディレクトリ構成

 Tomcatのインストール時のデフォルトのディレクトリ構成はTomcat 6から変更ありません。以下についてはTomcat 6と同じです。

  • インストール後のデフォルトのディレクトリ構成
  • 設定ファイル(server.xml、context.xmlなど)の格納場所
  • ログ出力ディレクトリ
  • 起動スクリプト格納ディレクトリ

クラスローダ階層

 クラスローダの階層もTomcat 6のころと同様で、変更ありません。

リクエスト処理のアーキテクチャ

 Tomcat 4時代から採用されているリクエスト処理のCatalinaアーキテクチャは変更なしで、そのまま採用しています。Tomcatが受け付けたリクエストは、リクエスト処理パイプラインによってServletまで到達し処理されます。

クラスタリング(セッションレプリケーション)

 若干のインターフェイスの改良はありますが、基本的には同じ仕様です。

「All-to-All」「primary-secondary」の2つのレプリケーション方式が利用可能となっています。

DBコネクションプール

 今までどおりApache Commons DBCPを使用し、バージョンはDBCP 1.4系(JDBC 4用)を採用しています。Tomcat独自のjdbc-poolを利用する場合は別途ビルドが必要です。jdbc-poolは近いうちに同梱されるかもしれません。

 では、Tomcat 7の新機能について紹介していきます。

【1】Webアプリのバージョン管理「Parallel deployment」

 「Parallel deployment」は、TomcatにおけるWebアプリケーションのバージョン管理機能です。ポイントは以下の5つです。

  • 同じコンテキストパスのアプリケーションが複数の異なるバージョンを持てる
  • 古いバージョンのセッションを持つユーザーは、そのバージョンのWebアプリケーションを実行
  • セッションを持たないユーザーは最新バージョンのWebアプリケーションを実行
  • Webアプリケーションのバージョンは##バージョンで指定。test##001.warとかsample##001とか
  • ユーザーは実行するアプリケーションのバージョンを意識しない

 以下のような動作になります。

 バージョンを持たない(初期バージョン)のWebアプリケーションを「AP」とした場合、APでセッションを作成したユーザーはそのセッション(Session A)を保持するAPでサービスを継続します。

 その後、AP##001の新しいバージョンのアプリケーションがデプロイされると、新しいユーザーはSessionをAP##001に作成します。Session Aを持つユーザーは、そのまま引き続きAPを利用します。

 さらに、AP##002がデプロイされた場合も、新規ユーザーは最新バージョンを、既存ユーザーは自分の保持するセッションを持つバージョンのアプリケーションを利用します。

 つまり、アプリケーションのバージョンが上がっても、ユーザーがセッションを保持する場合は、実行されるアプリケーションはそのセッションを持つバージョンのアプリケーションになります。

Tomcatが自動で行うバージョン管理

 上記のようなバージョン管理はTomcatが自動で行っており、ユーザーは自分が実際に利用しているアプリケーションのバージョンを意識しません。つまり、ユーザーはバージョンを意識することなく、今までどおりのパスで、「http://【ホスト】/【AP】/【XXX】」とリクエストするだけで、Tomcatがセッションを基に処理すべきバージョンのアプリケーションを選んで実行してくれます。

コンテキスト分のメモリを利用するので、注意

 なお、Parallel deploymentによりバージョン管理機能を利用すると、サービスを継続させながら自由にアプリケーションのバージョンが上げられますが、バージョンを上げるたびにコンテキストを配置するため、その分多くメモリを利用します。注意が必要です。

不要なバージョンは削除する必要があるので、注意

 また、現在のTomcatでは管理するセッションがなくなった古いバージョンのアプリケーションの自動削除は行われないので、システム管理者はアプリケーションの保持するセッションの数をチェックし、不要なバージョンのアプリケーションは削除するなどの運用対処も必要になります。

【2】メモリリークの可能性があるクラスを初期化

 Javaランタイム環境でシングルトンなクラスをロードするのにコンテキストクラスローダを使用し、コンテキストクラスローダの参照を保持するようなクラスは、コンテキストクラスローダがWebAppクラスローダであった場合にメモリリークを引き起こす可能性があります。

 このような問題に対する回避策は、メモリリークを引き起こす可能性のあるクラスをWebAppクラスローダにロードさせずに、あらかじめCommonクラスローダでクラスをロードしてしまうことです。

 Tomcat 7では、この回避策を実現するために、JreMemoryLeakPreventionListenerを提供します。JreMemoryLeakPreventionListenerはTomcatのライフサイクルリスナとして実装されており、Tomcatは起動時にJreMemoryLeakPreventionListenerに初期化イベントを通知します。このときのコンテキストクラスローダはCommonクラスローダなので、JreMemoryLeakPreventionListenerは、その初期化イベント処理で上記のようなメモリリークを引き起こす可能性のあるクラスを初期化することで、メモリリークを回避します。

 JreMemoryLeakPreventionListenerはの子要素として定義することが条件です。server.xmlで、すでにの子要素として定義されているので、デフォルトで動作するようになっています。

 中には、メモリリークかどうか分かりにくいものも存在しますが、現在どのようなメモリリーク防止機能があるかは、公式ドキュメントに記載しています。

 Tomcat 7では、多くのメモリリークの防止と検知機能を提供します。また、【2】を含め次ページで紹介する、メモリリークの防止と検知の機能のうち大部分は、Tomcat 6.0にバックポート(反映)済みです。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。