ASP ガイドライン

J.D. Meier
Microsoft Corporation

December 27, 1999

この記事は、もともと MSDN Online Voices のコラム "Servin' It Up" に掲載されたものです。

はじめに

Active Server Pages (ASP) アプリケーションの成功は、多くの場合、アーキテクチャと設計の選択にかかっています。広範囲にわたる ASP テクノロジーと今日のアプリケーションに内在する複雑さを考えれば、これらの選択は困難になる可能性があります。この記事では、ASP をベースとしたアプリケーションを成功させるための特別なガイドラインをご紹介します。

ガイドラインを原則に従って整理しました。これらの原則を応用して、ソリューションとテクノロジーの評価を行う判断基準にしてください。次にご紹介する原則は、経験を生かし、これまで成功してきた開発パターンを融合して作られたものです。

原則 1 : 標準を使用する

名前付け規則の確立とディレクトリ構造の標準化では、個々の ASP アプリケーションを理解して維持するために最低限、必要な能力な知識を得るまでに時間がかかります。ASP アプリケーションに公式な標準がないため、多くの開発者たちはいくつかの共通な方法を確立してきました。ここでは、一般的によく使われる方法について説明していきます。

ASP テクノロジーではこれらにスクリプト エンジンを使用しており、また、スクリプトの記述方法は基本的に自由なため、命名規則にはあいまいな部分があります。定義を明示的に行う言語では、変数は実際の型で宣言されます。ASP テクノロジーを使用する場合、通常、ASP コード内の変数の型は、実際のデータ型ではなくその用途に合わせて宣言されます。たとえば、Microsoft® Visual Basic® Scripting Edition (VBScript) で作業をする場合、VBScript のすべての変数がバリアント型 (Variant) だったとしても、正しい処理が行われた場合のフラグは vSuccess (v はバリアント型を表す) ではなく、bSuccess (b はブール型 (Boolean) を表す) で宣言されます。

次の表は、よく使われる名前付け規則の一部を示しています。

変数の接頭語

接頭語 使用される変数 変数の例
b または bln ブール型 bSuccess
c または cur 通貨型 (Currency) cAmount
d または dbl 倍精度浮動小数点数型 (Double) dblQuantity
dt または dat 日付型 (Date) および時刻型 (Time) dtDate
f または flt 浮動小数点型 (Float) fRatio
l または lng 長整数型 (Long) lMilliseconds
i または int 整数型 (Integer) iCounter
s または str 文字列型 (String) sName
a または arr 配列 aUsers()
o または obj COM オブジェクト oPipeline

データベース オブジェクトに対する変数の接頭語

接頭語 使用される変数 変数例
cnn Connection cnnPubs
rst Recordset rstAuthors
cmd Command cmdEmployee
fld Field fldLastName

スコープと使用法の接頭語

接頭語 説明
g_ Global.asa で作成される
m_ ASP ページに対してローカルまたはインクルード ファイル内でローカル
(接頭語なし) 非静的変数、プロシージャに対してローカルな接頭語

Knowledge Base (KB) の記事「Q110264 INFO: Microsoft Consulting Services Naming Conventions for Visual Basic」に名前付け規則に関する詳細が掲載されています。

ディレクトリ構造に関しては、さまざまなアプリケーションに一貫したホームディレクトリを使用してください。実際のアプリケーションのディレクトリ構造をどのように構築するかはユーザーしだいです。ただし、イメージ、ドキュメント、インクルード ファイル、およびコンポーネントはそれぞれ別のディレクトリに置くのが通例です。簡単な ASP アプリケーションのディレクトリ構造の例を紹介します。

ディレクトリ構造の例


¥SimpleAspAp
    ¥Docs
    ¥Images
    ¥Includes

優れたディレクトリ構造では、ディレクトリ内の各フォルダに対して、それぞれに NTFS の権限を設定することができます。また、ASP アプリケーション内部からの相対パスを利用することもできます。たとえば、default.asp ページが SimpleAspApp ディレクトリにある場合、次のコードを使用して Includes ディレクトリのインクルード ファイル top.asp を参照することができます。


./includes/top.asp

インクルードの拡張子が .inc ではなく .asp であることに注意してください。これはセキュリティ上の目的によるものですが、.inc ではなく .asp を拡張子として使用することにより Microsoft Visual InterDev® で色分けされた編集画面でコーディングを行うこともできます。

ASP アプリケーションの構造に関する詳細なヒントや秘訣については、「ASP Conventions (英語)」を参照してください。

原則 2 : サービスの下で稼動するように設計する

ASP はサービスの下で動作します。ASP アプリケーションの設計を行う場合、デスクトップ アプリケーションでは関係のなかったセキュリティ コンテキストやスレッドの問題に突然直面することになります。デスクトップ環境では、ユーザーは一般的に対話ユーザーとして単一スレッドを実行して作業を行い、現行のデスクトップにアクセスします。インターネット インフォメーション サービス (IIS) 下では複数のクライアント スレッドがさまざまなユーザー コンテキストを偽装し、アプリケーションを呼び出します。アプリケーションはシステム デスクトップに制限されます。

これはユーザーにとってどんな意味を持つのでしょう? IIS のセキュリティ モデルについて学習してください。また Visual Basic IDE の上ではきちんと実行されているからといって、ASP テクノロジーの下でも安全に動作するとは限らない点に注意してください。Visual Basic IDE は実行環境を厳密にシミュレートしているわけではありません。共通する設計上の誤りとして、ユーザー インターフェイスを必要とする .OCX を使用していること、スレッドセーフでないコンポーネントを使用していること、ASP テクノロジー下で特別なユーザー コンテキストを必要とするコンポーネントを使用していることなどがあります。最も簡単な問題を避けるには、アプリケーションから HKEY_CURRENT_USER (HKCU) レジストリ キーにアクセスしないということです (たとえば、HKCU に依存している Visual Basic の GetSetting 関数と SaveSetting 関数は呼び出さないでください)。また、ユーザーの操作が必要なメッセージ ボックスやその他のダイアログなども起動させないようにしてください。

次の記事は、ASP テクノロジーにおけるセキュリティと認証問題に関する優れた入門書です。

  • 「Authentication and Security for Internet Developers (英語)」
  • 「Q172925 INFO: Security Issues with Objects in ASP and ISAPI Extensions (英語)」

原則 3 : ビジネス ロジックをカプセル化する

ASP テクノロジーには、HTML 出力を生成するプレゼンテーション サービスがあります。つまり、ユーザー インターフェイスを生成します。ASP プレゼンテーション スクリプトからビジネス ロジックを分割する必要があります。COM コンポーネントを使用せずに ASP コードからビジネス ロジックを分割するのであれば、少なくとも保守性、読みやすさ、再利用のしやすさから、ビジネス ロジックを関数とインクルードに分割してください。モジュールに分けておくと、トラブルシューティングを行う場合や問題点を切り離す場合に便利です。

スクリプトから関数とメソッドを呼び出すだけで、"スパゲッティーのように絡みつくような煩雑なコード" を避けて ASP アプリケーションに構造を追加することができます。次に、ロジックを ASP コードからのメソッドの呼び出しに切り離す簡単な例を示します。


  <% Main()
     MyBizMethod()
     ...

     Sub Main()
               GetData()
               DisplayData()
     End Sub
 %>

この原則は、ASP 機能を含むテクノロジーを使用して作業を行う場合に応用できます。たとえば、Visual Basic WebClass で作業する場合は次のように応用することができます。

  • WebClass 自体は ASP コードを参照して HTML を生成しているので、WebClass に直接ビジネス ロジックを応用することはありません。これはプレゼンテーション層に当たるため、MTS/COM+ の下で WebClass を実行することはありません。
  • WebClass から別々にビジネス コンポーネントを呼び出し、MTS/COM+ の下で実行することができます。
  • WebClass フレームワークと WebClass ランタイムの余分なオーバーヘッドに依存するのではなく、ASP への参照を含む独自の COM コンポーネントを作成したり、ASP スクリプトを使用してビジネス コンポーネントを直接自動化することができます。

原則 4 : 最新のリソースを取得して早期に解放する

デスクトップからサーバーへの転送は一般的な問題です。デスクトップ環境出身の開発者たちは、サーバーの問題やリソースの共有について悩む必要がありませんでした。従来のデスクトップ アプリケーションでは、サーバーへの接続は単に時間を消費するプロセスでした。また、ユーザーの使い心地を改良するため、一般的にリソースを先に取得して後で解放していました。たとえば、多くのアプリケーションでは、その有効期間が終了するまで、データベースへの接続は開いたままでした。

ユーザーの拠点は完全に把握されて制御されており、バック エンドとフロント エンドが密接に連結されているため、この方法は、従来のデスクトップ アプリケーションでは何の問題もありませんでした。しかし、今日の Web アプリケーションに対しては、限られたサーバーのリソースに対してユーザーの拠点数が増加しているため適していません。ユーザー全体でアプリケーションを調整するためには、最新のリソースを取得して、それらをできる限り早期に解放する必要があります。

プーリングを行うことで、この手法をより効果的にすることができます。プーリングにより、複数のユーザーが最小限の待ち時間でリソースを共有することができ、サーバーへの影響も最小限に押さえることができます。たとえば、データベースで作業を行っている場合、ODBC 接続プーリングと OLEDB リソース プーリングを使用して、プールから接続を取得してデータベース接続のオーバーヘッドを最小限に押さえることができます。

ADO のプーリングの詳細については、「Microsoft Data Access Components におけるプーリング」を参照してください。

原則 5 : データベースを使用して複雑な状態管理を実現する

HTTP プロトコルがその威厳を失っている一方で、ASP 開発者たちは一般的に組み込みの状態保存メカニズムを持つ ASP 機能を使用しています。たとえば、ASP テクノロジーの組み込み Application オブジェクトを使用すると、開発者は、そのアプリケーションを使用するすべてのユーザーが共有するリソースを保存できます。ASP の組み込み Session オブジェクトを使用すると、シングル ユーザーに対するリソースを保存することができます。

ASP テクノロジーの Session オブジェクトで情報を保存すると簡単に状態を維持することができそうですが、これにはかなりのリソースがかかります。そして、拡張性を制限するもっとも大きな要因の 1 つになる可能性があります。アプリケーションの拡張性は、ユーザー数の増加に対してアプリケーションのパフォーマンスを保守するための基本的な機能です。すべてのユーザーを考慮すると、Session オブジェクトは、セッションがタイムアウトになるか破棄されるまでサーバー上のリソースを消費します。また、セッションはユーザーとサーバーを結び付けるため、ユーザーは Web ファームの利用を制限されることになります。できる限り状態管理に ASP の Session オブジェクトを使用しないでください。まったくセッションを使用しなければ、Web アプリケーションの Session 管理を無効にすることができます (IIS ドキュメントを参照してください)。または次の設定を利用して、ページごとに Session 管理を無効にすることもできます。


<%@ENABLESESSIONSTATE=False %>

単純なデータならば、Cookie、QueryString、または隠しフォーム フィールドを使用して ASP 要求の間の状態を維持できます。ただし、複雑な情報に関しては一般にデータベースを使用してください。よく使われるテクニックでは、各要求に対して一意識別子を生成してクライアントに送信し、隠しフォーム フィールドとして保存します。これ以降の要求では、この一意識別子を使用してデータベースからユーザーに関連付けられた状態情報が検索されます。この方法によって、高度な拡張性とより明解なコードが可能になります。

Cookie、QueryString、および隠しフォーム フィールドの使用法に関する詳細については、「Q175167 HOWTO: Persisting Values Without Sessions」を参照してください。

原則 6 : Server.CreateObject を使用してオブジェクトを作成する

ASP テクノロジーでは、<OBJECT> タグ、Server.CreateObject、および CreateObject のいずれかを使用してオブジェクトを作成することができます。それぞれのテクニックの動作はわずかに異なります。IIS 4.0 では、Server.CreateObject よりも <OBJECT> タグまたは CreateObject を使用する方がパフォーマンスの面で多少優れていますが、一般的には Server.CreateObject が好まれるようです。これにより、ASP アプリケーションはオブジェクトを認識します (IIS 5.0 では、Server.CreateObject とのパフォーマンスでの優位性の違いがなくなった点に注意してください)。

<OBJECT> タグでは、最初のメソッドが呼び出されるまでコンポーネントは作成されないため、リソースを節約することができます。Server.CreateObject は、ASP テクノロジーの組み込み Server オブジェクトを使用してコンポーネントを作成します。内部では簡単な CoCreateInstance を実行していますが、ASP はそのオブジェクトを認識しています。さらに、ASP テクノロジーのレガシ OnStartPage と OnEndPage が呼び出されます (IIS 4.0 では ObjectContext を使用してください)。単に CreateObject を使用する場合は、ASP テクノロジーを回避し、直接スクリプト エンジンを通して呼び出しが行われます。

ファイアウォールを通して呼び出しを行う場合、例外的に Server.CreateObject の代わりに CreateObject が呼び出される可能性があります。詳細については、「Q193230 - PRB: Server.CreateObject Fails when Object is Behind Firewall」を参照してください。

原則 7 : トラブルシューティングに必要な情報を十分に提供する

すべての ASP アプリケーションには、必ずエラー処理を含めるようにしてください。さらに、役立つ診断情報を提供するようにしてください。エラー情報の解説が詳細すぎることに文句を言うユーザーを見たことはありません。エラー ログには次の情報を必ず含めてください。

  • ユーザー コンテキスト (コンポーネントを使用している場合は GetUserName を呼び出すことができます)
  • スレッド ID (コンポーネントから GetCurrentThreadId を呼び出すことができます)
  • 時刻
  • 完全なエラー情報 (番号、ソース、および説明など)
  • パラメータ値

ASP 下で作業を行っているため、ファイルまたは NT イベント ログにこれらの情報を書き込むことをお勧めします。また、アプリケーション障害を診断する場合に便利な、重要なアプリケーション イベントを記録するアプリケーション イベント ログも作成してください。

次の記事に、エラー処理テクニックの詳細が掲載されています。

  • Charles Alexander 著、「Bulletproofing Your ASP Components (英語)」
  • 「Fitch & Mather Stocks: Web Application Design (英語)」
  • Web ページのエラー処理と回避 パート1: 基本事項
  • 「Handling and Avoiding Web Page Errors, Part 2: Run-Time Errors (英語)」
  • 「Handling and Avoiding Web Page Errors, Part 3: An Ounce of Prevention (英語)」

原則 8 : パフォーマンス、拡張性、および信頼性をテストする

おそらく操作性を確認する場合は別ですが、ブラウザを使用したテストは正確ではありません。アプリケーションのパフォーマンスに対する明確な目標を立て、Web Application Stress Tool などの読み込みツールを使用して負荷テストを行ってください。どの環境に何が適しているのか確認する必要がある場合は、次に紹介する一般的なガイドラインを利用してください。

  • 1 秒ごとに ASP 要求を測定してパフォーマンスのテストを行い、最小のしきい値を確立してください。一般的に、データベースへのアクセスを行わない単純な ASP ページの場合、1 秒間に少なくとも 30 ページを返します。コンポーネントを呼び出したりデータベースへのアクセスを行うページでは、1 秒間に少なくとも 25 ページを返します。
  • 予定したしきい値を 1 秒間の要求が下回るまでユーザー数を増やし、拡張性のテストを行ってください。
  • Web ファームからマシンを削除して信頼性のテストを行い、エラーや障害を確認してください。

テスト環境とファイアウォール直下の実稼動環境を一致させてください。これには費用がかかるように聞こえますが、ファイアウォールを考慮しなかったために仕事を失った開発者たちの話を聞いたことがあります。

ASP アプリケーションをテストする Web Application Stress Tool の使用方法については、「I Can't Stress It Enough - ASP アプリケーションのロード テスト」を参照してください。

原則 9 : 「分離」の使用を増やす

アプリケーション プロセスを保護するために分離を使用すると、サーバーの安定性を向上させることができません。インターネット アプリケーションの場合、分離はサーバーの停止およびアプリケーションでの問題を区別する言葉として使用されることがあります。IIS のメイン プロセス (InetInfo.exe) は通常優先的に保護する必要があります。何かコンポーネントを使用している場合は特に必要です。

IIS のメイン プロセスを保護するために一般的に利用されるテクニックでは、Web アプリケーションをそれぞれのメモリ領域で実行します。このオプションはインターネット サービス マネージャの Web ベースごとに設定することができます。プロセス間の操作上のオーバーヘッドのためにパフォーマンスが多少低下しますが、アプリケーションの保護によりもたらされるメリットはより大きいものになります。IIS 4.0 下では、インプロセスまたはアウトプロセス (OOP) のいずれかでアプリケーションを実行させることができます。OOP アプリケーションは Mtx.exe の新しいインスタンスの下で実行させることができます。IIS 5.0 には、別の分離オプションが追加されています。分離レベルは [低] (Inetinfo.exe に対してインプロセス)、[中] (DllHost.exe の共有インスタンス)、または [高] (DllHost.exe の非共有インスタンス) のいずれかに設定できます。

独自のメモリ領域に Web アプリケーションを分離する方法に加えて、信頼関係のないコンポーネントを分離する場合があります。信頼関係のないコンポーネントは、基本的に実稼動環境における時間のテストに対して耐性がありませんでした。これらのコンポーネントはサーバー パッケージで実行させることができるので、Dllhost.exe の新しいインスタンス下でも実行させることができます。

一般には、パフォーマンスと保護の両方を満足させるために、ライブラリ パッケージでコンポーネントを実行している間に、分離レベルを [高] に設定して Web アプリケーションを実行します。これにより、プロセス間の保護を最大限に行う一方で、操作上のオーバーヘッドを最小限に押さえることができます。

詳細については、「プロセス分離によるサーバーの信頼性向上」を参照してください。

原則 10 : スレッド プールを濫用しない

IIS 4.0 下では、ASP は MTS により管理されるスレッド (プロセッサに対して既定で 10 個) のプールを持っています。IIS 5.0 の場合、既定値は 20 です。各スレッドは、潜在的に多くのクライアントの要求を処理する貴重なリソースと言えます。そのため、時間のかかるデータベースの呼び出しなど、妨げとなるようなメソッドの呼び出しは避ける必要があります。ASP アプリケーションからクライアントへの応答を遅らせるような作業を行う場合は、キューの使用を検討してください。たとえば、NT 4.0 上では MSMQ を使用することができました。Windows 2000 ではキュード コンポーネントが使用できます。

STA (Single-threaded Apartment) コンポーネントを Session に保存しないでください。よくある落とし穴として、Visual Basic オブジェクトが Session スコープに埋め込まれる場合があります。これによりユーザーは単一スレッドにロックされてしまうので、スレッド プールの効果はなくなります。潜在するユーザーは、ユーザーのコンポーネントを有効にするために作成したスレッドを待つ間、ほかのユーザーによって妨げられることになります。その代わりに、ページごとの作成および破棄が可能な、状態を持たないコンポーネントを設計してください。

ヒント サーバーで、インターネット サービス マネージャを使用して ASP Script Debugging を無効にしてください。ASP Script Debugging が有効になっていると、ASP 実行は単一スレッドにロックされます。

詳細については、次の記事を参照してください。

要約

ASP アプリケーションの構築には、かなり広範な知識が必要とされます。ASP アプリケーションには、統一された規則がないという問題がありますが、これは面白い点でもあります。さらに、多くの開発者がデスクトップ環境からインターネットを開発しようとしていることも事実です。前述の原則を独自の ASP 開発に応用することによって、コスト面の問題を避け、優れた ASP アプリケーションを実現することができます。

J.D. Meier は米国東海岸で生まれて育ちました。Horace Greeley の助言に従って、MTS および ASP 技術を含むサーバー側コンポーネントと Windows DNA アプリケーションを専門とするデベロッパ サポート エンジニアとして働いています。