Tomcatって何ですか?
サーブレットの注意点
ここまでいいこと尽くめのように見えるサーブレットですが、注意すべき点もあります。
サーバのリソースを常に消費する
サーブレットはCGIと違い、リクエストに対する処理が終了した後も、プロセスを起動し続けながらリクエストを待つので、サーバのリソースを無駄に消費しているともいえます。これはサーバのリソースが限られる環境では問題になるかもしれません。
複数のスレッドが競合する可能性がある
1つのリクエストに対して1つのプロセスが起動されるCGIでは、メモリ空間やファイルといったリソースも別々に確保されます。しかしサーブレットでは1つのプロセスが持つリソースを複数のスレッドで共有しています。これはサーブレットの特徴でもありますが、同時に複数のスレッドでリソースの競合や 干渉が起きてしまう危険性をはらみます。そのためサーブレットプログラムでは、スレッドセーフなコードを書くように注意する必要があります。
サーブレットにはこのような注意点も存在しますが、それを補って余りある利点が認められ、特に大中規模Webアプリケーションの開発に広く利用されているのです。
サーブレット/JSPがどんな技術かは理解いただけたでしょうか。次にサーブレットの実行環境であるサーブレットコンテナについて見ていきたいと思います。
サーブレットコンテナの役割
サーブレットの仕組みの特徴は、Webサーバ外部のプログラムとして呼び出されるのではなく、Webサーバと連携して動作するサーブレットコンテナというモジュール上で実行される点にあります。
サーブレットの実行環境を提供
通常のWebサーバにサーブレットプログラムを配置しただけでは、動作させることはできません。サーブレットコンテナは、サーブレットを動作させる ために必要なモジュールである「Java Servlet API」を提供するとともに、サーブレットが動作するようにWebサーバを拡張します。
ライフサイクルの管理
サーブレットコンテナは、サーブレットのインスタンスを作成してコンテナ上にロードした際、init()というメソッドを呼び出し、サーブレットの初期化を行います。サーブレットがコンテナ上にロードされるタイミングは、サーブレットがはじめて呼び出された時ロードする、あらかじめロードしておくな どサーブレットコンテナの設定によって異なります。
- サーブレットのロードと初期化:init()メソッド
- サーブレットコンテナの主な役割に「サーブレットのライフサイクル管理」があります。サーブレットは javax.servlet.Servletインターフェースを継承したJavaクラスでなければなりません。Servletインターフェースはサーブ レットのライフサイクルを定義しています。すなわちサーブレットが呼び出されてから破棄されるまでの動作があらかじめ決められています。
- サーブレットの実行:service()メソッド
- サーブレットの初期化以降は、クライアントからリクエストがある度に「service()というメソッドを呼 び出します。service()メソッドは、HTTPリクエストのタイプ(GET、POSTなど)を判別し、doGet()、doPost()といった適 切なメソッドに渡します。これらのメソッドの実行が終了した後も、サーブレットはコンテナに常駐し、繰り返しリクエストを処理していきます。
- サーブレットの破棄:destroy()メソッド
- 管理ツールから支持があった場合など「destroy()」メソッドが呼び出されてインスタンスを破棄しま す。これによってinit()メソッドで取得したリソースなども開放されます。その後、ガーベジコレクションされファイナライズされます。その Servletのインスタンスのservice()メソッドが再び実行されることはありません。destroy()メソッドが呼び出されるタイミングは サーブレットコンテナの種類によって異なる場合があります。
このように初期化・破棄を一度しか行わないことで、複数のリクエストに対しても必要な処理だけを繰り返し実行させることができるため、パフォーマンス向上がはかられています。
セッション管理
コンテナはCookieを通じてクライアントの識別を管理しますが、クライアントのWebブラウザでCookieが無効なっていた場合は、URLを書き直してセッションを維持します。このCookieがONかOFFかの判別もコンテナは自動で行ってくれます。
Webアプリケーションに必要なサービスの提供
コンテナは「初期化のパラメータを用意する」「データベースへの接続を可能にする」「多言語に対応したリソースをサーブレットが見つけて参照できるようにする」といった各種のサービスも提供します。
JSPのコンパイル
コンテナはJSPが最初に呼ばれたときに、これを自動的にコンパイルしてサーブレットクラスに変換します。これはJSP APIによるものなので、厳密にはサーブレット技術とは区別されるのですが、一般にサーブレットコンテナの機能として扱われています。