ガイドライン: J2EE アプリケーションの状態の設計
トピック
概要

アプリケーションの状態を効率的に管理することは、分散アプリケーションの設計では重要です。
このガイドラインでは、J2EE アプリケーションの状態管理を行う上で共通の設計の考慮事項とメカニズムについて概要を述べます。
状態管理に関連した考慮事項の設計は、プロジェクトの推敲フェーズに対応する必要があります。ソフトウェア・アーキテクトは、状態管理の一般的なアプローチについて、分析/設計作業分野の『 ワークフローの詳細: アーキテクチャー候補の定義』に関連した作業の一部として検討する必要があります。『 作業:
アーキテクチャー分析』では、ソフトウェア・アーキテクトは、アプリケーションに対するスケーラビリティーとパフォーマンスの要求を検討し、アプリケーションのパフォーマンス目標を満たすために必要な状態管理の手法を決定します。推敲フェーズの過程を経てアプリケーション設計の洗練が進むにつれ、アーキテクトは、J2EE 固有の設計メカニズムと実装メカニズムを定義して、『 作業: 設計メカニズムの識別』でのアプリケーションの状態情報を管理できるようにする必要があります。
『概念:
J2EE 導入構成』で説明しているとおり、J2EE アプリケーションは、1 対多の物理層 (コンピューター) に分散された複数の論理レイヤーで構成することができます。以下のセクションでは、状態管理の技術概要に続き、複数のアプリケーション層で使用可能な各種状態管理の設計メカニズムと実装メカニズムについて説明します。
ソフトウェア・アーキテクトは、どのメカニズムを『成果物: ソフトウェア・アーキテクチャー説明書』の一部として選択したかを文書化する必要があり、これらのメカニズムの使用についてプロジェクト固有の設計ガイドラインに組み込む必要があります。
技術概要

なんらかの形でインターネットと相互作用する分散アプリケーションを作成する傾向がますます強まっています。インターネットの基盤は本質的にステートレスなものですが、どのようなビジネス・アプリケーションを作成するとしても状態の管理は不可欠です。例えば、インターネット・アプリケーションでユーザーがページ a からページ b へのリンクをクリックするとします。ページ b への要求を処理するアプリケーションは、ページ a の処理に使用する情報へのアクセス権はありません。このような振る舞いは、静的な Web ページでは容認されますが、多くのビジネス・アプリケーションでは、直前の処理についての情報が必要となります。このような場合に使用するのが、J2EE による状態管理メカニズムです。
一時状態と永続状態
状態管理のガイドラインについて詳細に述べる前に、状態情報のタイプを区別することが重要です。状態情報は、大きく 2 つのカテゴリーに分けることができます。一時的なもの (アプリケーションがアクティブである間のみ存在する) と、永続的なもの (アプリケーションの終了後も存在する) です。
一時状態の情報は、この情報を保持するエンティティーがアクティブである間のみ存続します。例えば、通常の Java クラスのフィールドとして格納された状態情報が挙げられます。このクラスをホスティングするコンテナーがなんらかの理由で終了した場合、データがバックアップ・サーバーなど、どこかに複製されていない限り、状態情報は失われます。
永続状態は、状態情報の保持に使用されるデータ・ストアがある限り存在します。永続状態の情報は、通常ファイルやデータベースに保存され、アプリケーションで必要な場合にロードされます。永続状態の情報に対する変更は、データベースに書き戻す必要があります。永続データ・ストアの整合性と回復可能性は、アプリケーションがアクセスしているデータの整合性と回復可能性と矛盾のないようにしなければなりません。永続状態の例として、リレーショナル・データベースなどのデータ・ストアに保存された情報が挙げられます。
セッション状態

Web クライアントは、ページからページへ移動する間にもショッピング・カート内の商品などクライアント固有の情報を保持するような、複数ブラウザーの要求を作成する機能が必要な場合があります。Web アプリケーションは、セッション ID の作成によってこれに対処し、状態データをこのセッション ID と関連付けます。セッション ID と、関連付けられた状態はセッション状態として参照されます。
セッション状態とは、短期間 (数日ではなく、数分や数時間)、特定のクライアントの Web アプリケーションとの相互作用に関連付けられたデータです。したがって、セッション状態は短期間存続するデータで、通常はリソースの消費を避けるためにタイムアウト時間の後で削除されます。
後のセクションで説明するように、セッション状態はクライアントまたはサーバーに保存されます。Web ベースのアプリケーションでの重要性から、J2EE プラットフォームは、セッション状態の管理用に特にカスタマイズされたメカニズムを提供します。
基本的な永続性メカニズム 
以下に、状態を保存するために Web アプリケーションで使用する一般的なメカニズムを示します。
クッキー
クッキーは、Web ベースのクライアントに保存される小さなテキスト・ファイルです。サーバーはクライアント上にクッキーを保存できます。以降のクライアント要求はサーバーにクッキーを送信し、これによりサーバーは、クッキーに保存された状態データにアクセスします。
クッキーには、次の問題点があります。
- 多くのユーザーは、クッキーにセキュリティーとプライバシー上の問題があると考えてクッキーを無効にします。
- クッキーのヘッダー・サイズに制限があるため、データの保存量にも限界があります。
- Wireless Access Protocol (WAP) など、クッキーをサポートしないプロトコルがあります。
- クライアントが別の場所 (別のマシンなど) からログインした場合、ほかの場所で保存されたクッキーは利用できません。
- 状態データは、文字列型の値で表現する必要があります。
URL の再書き込み
URL の再書き込みは、各ページで参照した URL にセッション状態を埋め込むメカニズムです。Web サーバーがクライアントに送信するページを生成する際、セッション状態をページの URL にエンコードします。ユーザーが URL をクリックすると、URL に保存された状態データがサーバーに送り返され、それによってセッション・コンテキストを再確立できます。HTML の非表示フィールドを使用する同様のメカニズムもあります。これらのメカニズムには次の問題があります。
- 特定のセッション内のすべてのページをサーバーで処理する必要があります。そうしないと、サーバーはセッションを追跡できなくなる可能性があります。
- クライアントがブラウザーをシャットダウンしたり、URL の入力やブックマークの使用によって特定の URL にリンクしたりすると、状態は存続しません。
- クッキーと同様、状態データは、クライアントがほかの場所からログインした場合には使用できません。
- クッキーと同様、状態データは、文字列型の値で表現する必要があります。
フラット・ファイル
フラット・ファイルは、永続状態の情報を保持する最も単純な方法です。フラット・ファイルは、初期状態の値を設定するために、初期化時に読み込まれます。状態が変更されるたびに、状態の保存のためにファイルに再書き込みする必要があります。フラット・ファイルにアプリケーション状態を保持する方法の欠点として、次のことが挙げられます。
- アプリケーションのスケーラビリティーに悪影響を及ぼします。これは、アプリケーションの状態変数を更新してフラット・ファイルに再書き込みする間、グローバル・データへのアクセスができないよう、アプリケーション・オブジェクトをロックする必要があるためです。
- ほとんどの場合、データを更新するには、ファイル全体を再書き込みする必要があります。
- フラット・ファイルには、必ずしもエラー時の回復機能があるとは限りません。
XML

XML ファイルに永続状態の情報を保存する方法は、フラット・ファイルの場合よりも高度です。
フラット・ファイルと比較した、XML ファイルにアプリケーション状態を保存する利点は、次のとおりです。
- XML ファイルは、フラット・ファイルにはない構造を備えています。
- XML ファイルは、標準 API を使用して構文解析できます。
- 一般に、XML ファイルは移植性に優れています。
データベース

永続状態の情報をデータベースに保持することにより、最大限の回復可能性が得られます。
データベースにアプリケーション状態を保存する方法の利点として、次のことが挙げられます。
- テーブル設計による構造化が可能です。
- アプリケーション変数の更新時に、アプリケーション状態全体を再書き込みする必要がありません。
更新情報のみ再書き込みすれば済みます。
- アプリケーション状態の回復と実動データベースの回復を調整することにより、一貫性を保つことができます。
- 高い信頼性が要求される状況で、データベース・サーバーをクラスター化できます。
Java Database Connectivity (JDBC) API を使用してデータベースにアクセスできます。
JDBC は、スプレッドシート、フラット・ファイルなどほかの表形式のデータ・ソースのアクセスにも使用できます。
J2EE 固有のメカニズム 
J2EE プラットフォームでは、状態管理の固有のメカニズムをいくつか提供しています。これらは、これまでに説明した基本的なメカニズムを 1 つ以上使用して構成できる高水準のメカニズムです。
サーブレット・コンテキスト

サーブレットは、サーブレット・コンテキストを使用して、複数のクライアントとクライアント・セッションに適用可能なデータを保存できます。
サーブレット・コンテキストに保存されたデータは、実際には J2EE アプリケーションのグローバル変数です。結果として、アプリケーション状態の使用はアプリケーション設計に重要な影響を与えます。ソフトウェア・アーキテクトは、サーブレット・コンテキストが適切かどうか決定する『作業: 設計メカニズムの識別』において、次の点を考慮する必要があります。
- サーブレット・コンテキストは単一プロセスで保持され、複数サーバー (クラスター) で共有できません。
このことがアプリケーションのスケーラビリティーのニーズに合わない場合、アーキテクトは状態をセッション状態として保存することを考慮する必要があります。
- サーブレット・コンテキストはプロセス・メモリーの一部であるため、通常、プロセスの終了時には保持されません。
- 複数のスレッドからグローバル・データにアクセス可能です。グローバル・データのロックと同期が、アプリケーションのスケーラビリティーに影響を及ぼす場合があります。
HTTP セッション・オブジェクト 
サーブレットと JSP は、特定のクライアント・セッションに関連するデータを HTTP セッション・オブジェクト内に保存できます。セッション・オブジェクトにデータを保存する場合、複数サーバーからアクセス可能なセッション・データの作成方法に関する問題があります。同一サーバーへのクライアント要求をルーティングする機能を提供するベンダーもあります。これは、「サーバー・アフィニティー」と呼ばれます。
HTTP セッション・オブジェクトは、クライアント要求の処理中にサーバーで使用できますが、次の要求までの間サーバーに保存される場合とされない場合があります。サーバーは、セッション情報を保存するのに、クライアント上のクッキーやサーバー上のファイルまたはデータベースを使用するなど、前述の任意の基本的な永続性メカニズムを使用する構成が可能です。メモリー・アクセス・サーバーでセッション・データを複製する機能も提供します。
サーバーの構成によってメカニズムを選択します。JSP とサーブレットは、選択したメカニズムとは独立してコーディングされ、サーブレット仕様で指定した API を使用してセッション・オブジェクトにアクセスします。
Enterprise JavaBeans 
Enterprise JavaBeans には、データベースやファイルなど前述の低レベルのメカニズムを基礎とした、データ保存の高レベルのメカニズムを備えています。エンティティー Bean が長期間データの保存に使用されるのに対して、ステートフルなセッション Bean は、特定のクライアント・セッションと関連付けられたデータの保存に使用されます。EJB で保存された状態について詳しくは、『ガイドライン: EJB』を参照してください。
セッション状態の設計
Web クライアントは、ページからページへ移動する間にもショッピング・カート内の商品などクライアント固有の情報を保持するような、複数ブラウザーの要求を作成する機能が必要な場合があります。Web アプリケーションは、セッション ID の作成によってこれに対処し、状態データをこのセッション ID と関連付けます。 次のいずれかまたは両方のメカニズムによって、セッション ID 自体がクライアントに保存されます。
- クッキー - クライアント・ブラウザーは、要求ごとにこのクッキーをサーバーに送信し、サーバーがセッション状態を再確立できるようにします。
- URL の再書き込み - サーバーからクライアントに配信されたページの URL にセッション ID がエンコードされます。ユーザーがそのような URL をクリックすると、セッション ID がサーバーに送信され、サーバーはセッション状態を再確立できます。
サーバーは、選択されたアプローチを使用するよう構成されます。サーブレットと JSP は、メソッドの構成に関係なく動作するようにコーディングする必要があります。特に、URL をエンコードするには、必ずHttpServletResponse.encodeURL() メソッドを使用してください。このメソッドは、URL 再書き込みが有効かどうかをチェックし、有効であればエンコードを実行します。
セッション ID と関連するデータは、JSP とサーブレットでアクセスできる HTTP セッション・オブジェクト、またはセッション Bean に保存できます。
セッション ID と関連するデータはいずれも、タイムアウトを設定することで、長期間使用しないセッション・データがリソースを無制限に消費することがなくなります。
アーキテクトは、適切なタイムアウト時間を選択する必要があります。
適切なメカニズムの選択
アーキテクトは、単純さと性能上の理由から、クライアントでのセッション状態の保存を考慮する必要があります。クライアント上で状態を管理および保存する場合、サーバーは、状態情報の保存やその一貫性の保証のためにリソースを消費せずに済みます。クライアントに状態情報を保存する欠点としては、情報が必要になるたびにサーバーに送信する必要があることから、ネットワークの待ち時間に関する問題が生じることが挙げられます。クライアントに公開したくないセッション状態データが存在する場合、セキュリティーを考慮する必要があります。この場合、暗号化することもできます。
アプリケーションが大量のセッション状態を持つ場合、サイズと型の制限が総じて少ないサーバー上にこの状態を保存することをお勧めします。
一般に、プレゼンテーションが重要な問題となるセッション状態は、HTTP セッション・オブジェクトに格納し、ステートフル・セッション Bean は、ビジネス論理を正しく実装するのに必要な状態を含む必要があります。状態データの重複は避ける必要があります。重複した状態データがあれば HTTP セッションに移動させ、必要に応じてこのデータをセッション Bean のメソッド呼び出し時にパラメーターとしてセッション Bean に渡してください。
サーバーに保存されたセッション・データがサーバー・ノードの障害があっても存続する必要がある場合は、セッション・データの保持または複製のためのメカニズムの使用を検討してください。
長期間存続状態の設計
セッション・データは、タイムアウトになるまで短時間存続するクライアント・データに使用します。
より長時間存続するデータが必要となる場合もあります。
そのようなデータに合う適切なメカニズムは、保存するデータの性質によって決まります。
クッキー、フラット・ファイル、XML ファイル、データベースなどが選択できます。データベース・アクセスについては、通常、エンティティー Bean が最良の選択になります。詳しくは、『ガイドライン: エンティティー Bean』を参照してください。
|