インターネット インフォメーション サービス

ASP.NET アプリケーションを拡張する : 得られた教訓

Richard Campbell

 

概要 :

  • 開発および IT チームによる共同作業の重要性
  • 重要な拡張戦略について理解する
  • チーム間で知識を共有する
  • 主要な知識について意見を一致させる

目次

拡張の基礎
意見の一致
ネットワーク チームが開発チームから得る必要がある情報
開発チームがネットワーク チームから得る必要がある情報
話を拡張に戻します
協力して火を消し止める

私がコンサルタントとしてこれまでに成功させた ASP.NET アプリケーションの拡張は、開発者 (アプリケーションの構築者) と管理者 (アプリケーションの実行者) が共同作業を行うことによって実現されました。残念ながら、この共同作業の必要性は、アプリケーション

ライフサイクルの初期段階では明らかにならない場合があります。このため、私がアプリケーション ライフサイクルに関与するのは、その初期段階ではなく、最終段階で問題が発生したときだけです。

これはまったくの真実ですが、最初から効率的に拡張できるアプリケーションは存在しません。最初からすべてを成功させることは不可能です。アプリケーションの拡張を成功させるには、アプリケーションがどのようにして構築されたか、およびそのアプリケーションが実行される運用環境はどのようなしくみになっているかを理解する必要があります。つまり、開発チームとネットワーク チームの両方から情報を収集する必要があります。知識を共有することなく、成功を収めることはできません。

拡張の基礎

拡張を行う前に、実際に ASP.NET アプリケーションを拡張するために必要な知識について学習しましょう。一般的に使用される戦略としては、専門化と分散の 2 つがあります。大規模な ASP.NET アプリケーションの拡張では、ほとんどの場合、両方の戦略が使用されます。また、ASP.NET アプリケーションの拡張に役立つあらゆる方法は、このいずれかの戦略に分類されます。

専門化では、アプリケーションの要素を分割し、それらを個別に拡張できるようにします。たとえば、ASP.NET ページの表示に使用するサーバーとは別に、専用のイメージ サーバーを構築する場合があります。イメージ サーバーの最適な構成は、ASP.NET サーバーとは大幅に異なります。また、イメージの要求をアプリケーションの他の部分から分離することによって、サードパーティ製のリソースを使用してイメージを提供することもできます。他のリソース ファイルにも同じ方法を適用できます。

これに対して分散は、通常 Web ファームと呼ばれる複数のサーバーに、アプリケーションを対称的に分散させます。ASP.NET アプリケーションは分散に最適です。これは、個々のページ要求が比較的小規模で、特定のユーザーの対話が他のユーザーに大きく依存するからです。分散は、まさに "スケールアウト" という考え方の表れです。スケールアウトでは、中程度のパフォーマンスを提供する複数のサーバーが連携してユーザーにサービスを提供するので、パフォーマンスの高い 1 台の大規模なサーバーがすべての処理を行う "スケールアップ" とは異なります。

専門化と分散を組み合わせると、アプリケーションの中でパフォーマンスの強化が必要な要素のみを分散させることができるので、効率が向上します。たとえば、専用のイメージ サーバーを作成したが、まだイメージの提供速度が不十分である場合は、アプリケーション全体用のサーバーを追加せずに、イメージ サーバーを追加できます。これらの戦略を考慮することは、ASP.NET アプリケーションのパフォーマンスと拡張性を強化するうえで重要です。

意見の一致

どの ASP.NET アプリケーションのライフサイクルでも、高い確率で開発チームとネットワークまたは IT チームのミーティングが開かれます。運が良ければ、このミーティングはアプリケーションを展開する前に開かれますが、問題が発生してから開かれることもあります。たとえば、テスト環境で正常に動作したアプリケーションをユーザーの環境で実行したときに、十分なパフォーマンスが得られない場合などが考えられます (このような状況で私たちコンサルタントにお呼びがかかります)。

開発チームとネットワーク チームのミーティングを開く主な目的は、情報を交換することです。開発チームはアプリケーションに関する重要な知識を持っており、ネットワーク チームは運用環境に関する知識を持っています。各グループはもう一方のグループのデータを理解する必要があるので、ミーティングを開く時期がアプリケーション ライフサイクルの早い段階であればあるほど有効です。

問題が発生して初めてミーティングを開くことは避けてください。2 つのチーム間で十分な共通理解がなければ、アプリケーションのパフォーマンスが要件を満たしていない理由を突き止めるのは非常に困難です。また、一方のチームが守りに入って問題の原因をすべてもう一方のチームに押し付けるという事態も非常に発生しやすくなります。問題の原因は常に両方のチームにあるので、非常に複雑な問題が発生した場合は、必ず両方のチームが解決に当たる必要があります。

ただし、問題が発生していない場合でも、このようなミーティングを進めるのは非常に大変です。過去に私が開いたミーティングでは、ネットワーク チームがテーブルの片方の側に座り、開発チームがもう片方の側に座りましたが、最初は両者の見つめ合いになってしまいました。話を進めるために、私はミーティングの主な目的が知識の交換であることを説明しました。だれが口火を切るかは問題ではありません。それではまず、ネットワーク チームが開発チームから得る必要がある情報について説明します。

ネットワーク チームが開発チームから得る必要がある情報

どの ASP.NET アプリケーションにも独自の可変要素が含まれますが、すべての場合に当てはまる重要な要素があります。そのうちの 1 つが web.config ファイルです (図 1 参照)。web.config は、開発とネットワークに共通する要素です。このファイルは開発チームによって構成されることもあれば、ネットワーク チームによって構成されることもあります。どちらの場合も、web.config の内容によってハードウェアとネットワークの構成が制限され、アプリケーションの動作が直接その影響を受けます。web.config ファイルの詳細を説明するには書籍 1 冊分のスペースが必要になってしまうので、ここではポイントのみを説明しますが、どちらのグループも web.config ファイルについて学習し、その内容によって提供される構成や、それぞれの設定がアプリケーションと環境に与える影響を理解し、意見を一致させる必要があります。

fig01.gif

図 1 アプリケーションのいくつかの設定とカスタム エラーの構成を含む基本的な web.config (画像をクリックすると拡大表示されます)

たとえば、web.config の <authorization> セクションでは、アプリケーション内でどのようにユーザーを認証するかを指定し、依存関係を定義します。アプリケーションで Windows® 認証を使用する場合、そのアプリケーションは Active Directory® に依存する可能性があります。フォーム ベースの認証を使用する場合は、ユーザー アカウントのデータ ストアに依存することになります。このセクションの内容については、確実に話し合う価値があります。

特筆すべきは、ユーザーにエラーがどのように通知されるかを指定する <customErrors> セクションです。設定は複雑ではありませんが、どのようなエラー ページを表示するかについて理解するためだけでも、このセクションについて話し合う価値はあります。共同作業サイクルの初期段階では、おそらくカスタム エラー ページは存在しないので、このページについて話し合うことをお勧めします。

web.config の <appSettings> セクションは、特に重要な意味を持ちます。開発者はこのセクションに、データベースの接続文字列など、広い範囲で使用される値を指定します。また、このセクションは依存関係の基盤にも適しており、フェールオーバーや移行などの計画時にも重要な役割を果たします。<appSettings> は完全なカスタム セクションであり、どのような値でも指定できるので、指定した値の意味を伝えるために多くの説明が必要になる場合があります。このセクションにはよく値が孤立 (アプリケーションのどの部分でもこの値が使用されない事態が発生) します。

開発チームが <appSettings> を使用していない場合、ネットワークまたは運用チームは、そのセクションを使用するよう開発チームに要求した方がよいでしょう。このセクションにすべてのデータベース接続文字列を指定しておけば、単純なフェールオーバー戦略を効率的に作成できます。データベース サーバーで障害が発生した場合、代わりの文字列を挿入し、別のデータベース サーバーを参照できます。開発サイクルの初期段階でこの機会を得ることによって、アプリケーションの信頼性と保守性を強化できます。

最後に、拡張という観点から非常に重要な意味を持つ要素は <sessionState> タグです。このタグでは、アプリケーションのセッションに関するデータの格納先を指定します。既定では "InProc" が指定されており、これはセッション データが ASP.NET アプリケーションと同じプロセス空間に格納されることを意味します。セッション データを同じプロセス内に格納するように構成することは、負荷分散の観点から見ると厄介です。これは、常に特定のユーザーからの要求を、セッション データが格納されている同一のサーバーで処理する必要があるからです。このセクションは、拡張方法とフェールオーバーの実装方法に直接影響を与えるので、開発チームとネットワーク チームがこのことについて話し合う価値は大いにあります。早い段階で話し合っておけば、ビクビクしながらアプリケーションをデバッグする必要もなくなります。

セッション状態の話題になれば、通常はそこからアプリケーションの負荷分散要件に関する話題にスムーズに移行できます。環境によっては、特定の機能が実装された専用の負荷分散ハードウェアを使用する場合もありますが、アプリケーションでこれらの機能に対処できなければ、あまり意味がありません。私は、セッション データを同じプロセス内に格納する ASP.NET アプリケーションでハードウェア負荷分散を使用する環境を担当したことがあります。この環境では、セッションが突然終了することがありました。アプリケーション内にバグが存在することも考えられましたが、そうではなく、構成に誤りがありました。

ネットワーク チームは、アプリケーションに適した負荷分散構成に関する正確な情報を開発チームから得る必要があります。この双方向のやり取りで、使用できる負荷分散構成と、アプリケーションで対処できる負荷を確認します。アプリケーション ライフサイクルの早い段階でこの話し合いを持つことの大きな利点は、異なるプロセスにセッション データを格納する、アフィニティを使用しない負荷分散構成を前もって計画できることです。

ASP.NET アプリケーションを展開する準備が整う (または展開の初期段階に達する) ころには、開発チームのメンバは、アプリケーションの高速および低速な部分を熟知しています。最も重要なのは、これらのメンバがシステム内のボトルネックや危険性の高い部分を認識していることです。ネットワークまたは運用チームは、これらのボトルネックについて理解することによって、前もって問題の発生に備えたり、問題を回避したりできます。

たとえば、以前担当した環境では、毎晩あるアプリケーションが稼動していない時間帯に、そのアプリケーションで大量のデータを読み込む処理を実行していました。開発チームはそのデータ読み込みメカニズムを構築し、テストし、そのしくみを理解していました。また、この処理はデータベースに大きな負荷を与えるが、効果が高く、問題の解決に適した方法であることを認識していました。

ただし、開発者はこの処理が実行されることをネットワーク チームに報告せず、実行時刻を午前 1 時に設定しました。これはデータベースのバックアップが実行される時刻とまったく同じです。データベースはオンラインのままでしたが、データベースに送信されたすべてのトランザクションがトランザクション ログに記録されるので、バックアップ処理のパフォーマンスは低下しました。

競合が検出されて初めて、データの読み込みとバックアップを同時に実行したときに作成されるデータベースのトランザクション ログによって、ディスク領域がいっぱいになることがわかりました。データの読み込みを実行する時刻を午前 3 時に変更することによって、問題は完全に解決されました。

このような負荷について早い段階で話し合いを持つことによって、後からアプリケーションで問題が発生する可能性を大幅に低下させることができます。

開発チームがネットワーク チームから得る必要がある情報

ミーティングで、ネットワーク チームが開発チームに情報を提供するときは、まずネットワーク図を使用して説明することを強くお勧めします。ほとんどの場合、開発者はネットワークを図 2 のようなものと考えます。つまり、ネットワークが存在せず、Web サーバー、ブラウザ、およびインターネットのみが存在するようなイメージを持っています。

fig02.gif

図 2 開発者が考える単純なネットワーク図 (画像をクリックすると拡大表示されます)

もちろん実際はもっと複雑です。図 3 も単純化されていますが、こちらの方がより現実に近い構造を表しています。図 3 を見てすぐに、仮想プライベート ネットワーク (VPN) ユーザーはどのようにアプリケーションを操作するのか、内部ユーザーとパブリック ユーザーの認証はどのような点で異なるのかなど、さまざまな疑問が浮かぶと思います。

fig03.gif

図 3 開発者が理解する必要がある実際のネットワーク (画像をクリックすると拡大表示されます)

単にネットワーク図を提供するだけでは不十分であることは明らかです。図を見ただけで、アプリケーションに影響を与える要素について正確に理解することは不可能なので、ネットワークについて詳しく説明する必要があります。この説明は、実際のパブリック ユーザー、VPN ユーザー、および内部ユーザーの接続プロセスを例に挙げて行う必要があります。また、特に複雑な DMZ 形式のネットワーク アーキテクチャで使用されるさまざまなファイアウォール規則について話し合うことによって、アプリケーションで発生する可能性がある問題を確認します。

言うまでもなく、アプリケーションを展開する前 (開発を始める前でもよいでしょう) に、これらすべての内容について話し合うことが一番ですが、何があってもどこかの時点ではこのような話し合いを持ち、全員がネットワーク図の内容を完全に理解することが重要です。

ネットワークの構成はフェールオーバーおよび冗長性モデルにも影響を与えますが、なんらかのソフトウェアによるサポートを提供するか、少なくとも障害時の動作を認識しなければ、これらのモデルが計画どおりに機能することはほとんどありません。このため、どのような障害が予想されるかについて、細かい部分まで話し合う必要があります。データベース クラスタを実装している場合、データベースへのアクセスに関連するコードが影響を受けることになります。たとえば、サーバー間の切り替えが発生した後でクエリを再試行できるか、冗長なサイトを使用できる場合はどのようにしてデータをそのサイトにレプリケートすればよいか、あるサイトから別のサイトへの切り替えをどのように実行するかなどについて話し合う必要があります。

もう一度言いますが、早い時期に話し合いを持つのが一番です。ただし、時期が遅くなってもまったく話し合わないよりは効果があります。アプリケーション ライフサイクルにかかわるすべてのメンバが、各構成要素のしくみについて理解する必要があります。必要なときに機能しないフェールオーバー ソリューションを実装しても、ストレスのもとになるだけです。

最後に、共有する必要があるもう 1 つの重要なネットワーク リソースは運用ログです。私はいつも、運用ログを開発チームに公開することを推奨しています。たいていネットワーク チームは、「言ってくだされば送りますよ」という反応を返しますが、これでは不十分だと思います。開発者が自分たちでログを (通常はバックアップ サイトから) 取得できるようにした方が効果的です。

問題が発生した場合、運用ログは必要不可欠です。多くの場合、これらのログは、実際にどのような問題が発生したかについて、事実に基づいた真正なデータを提供する最も有用な (かつ唯一の) 情報源になります。ただし、運用ログは通常の状況でも同様の価値をもたらします。開発者は運用ログに定期的にアクセスすることによって、新しく実装した機能がどのように動作するかを確認できます。また、新しい機能が期待どおりに動作しない場合は、そのことに気付き、危機的な状況を迎える前に問題を解決することもできます。全員が運用ログにアクセスできれば、問題に対して迅速に行動を起こし、それらを解決できます。

話を拡張に戻します

ネットワーク チームと開発チームのミーティングにおいて大事なのは、ASP.NET アプリケーションの拡張に関する問題の全容を理解することです。実際にアプリケーションを運用する環境は、そのアプリケーションで実行するコードの動作に直接影響を与えます。また、拡張に関するすべての戦略が、運用環境でのアプリケーションの動作に影響を与えます。アプリケーションの中で SSL に関連する部分を分離するなどの専門化戦略を適用するには、ネットワーク環境に変更を加え、場合によってはサーバー自体に変更を加えることが必要になる場合もあります。

キャッシュの使用など、一見コード中心の変更のようでも、それが環境に影響を与える可能性があります。これは、ASP.NET アプリケーションにデータ キャッシュ機能を追加すると、メモリの使用率が増加する代わりに、データベースを呼び出す回数が減少するからです。このため、必要な ASP.NET サーバーの数が増加したり、サーバー上でのワーカー スレッドの再利用回数が増加すると、ネットワーク監視機能によってイベントが発行される場合があります。

ASP.NET アプリケーションの拡張は、開発チームとネットワーク チームの両方に影響を与えるので、意思決定プロセスにはどちらのグループも参加する必要があります。共同作業を行えば、それぞれのチームが別々に作業していたときには発見できなかった独自の解決策が生まれるでしょう。たとえばネットワーク チームは、開発チームが社内の既存のハードウェア ソリューションを活用して、パフォーマンスおよび拡張要件を満たすアプリケーションを作成できる可能性があることに気付くかもしれません。アプリケーションと環境について詳しく話し合うことによって、このような機会を得ることができます。

協力して火を消し止める

ASP.NET アプリケーションの拡張に関する参考資料

拡張時に問題が発生するのは必ずしも悪いことではなく、たいていは良いことです。この問題は、アプリケーションを実行しようとしているユーザーの多さが原因で発生するので、アプリケーションの価値が証明されたことになります。ただし、この状況に対処し、アプリケーションを正常に動作させなくてはなりません。

拡張時の問題は、別のことが原因で発生する場合もあります。たとえば、企業が宣伝活動を行っている場合や企業のことがブログに書かれた場合、非常に多くのソーシャル ネットワーキング サイト ユーザーによってこのアプリケーション (Web サイト) が参照された場合など、さまざまな状況が考えられます。そして突然、問題の火を消し止めてアプリケーションの実行を継続する必要が生じます。ご想像のとおり、このようなシナリオが実際に発生する前に、対処方法を準備しておくことが一番です。開発チームとネットワーク チームのミーティングを締めくくるときに、組織でこのような問題に対処するには共同作業が必要であることを説明するとよいでしょう。

問題の解決に関する疑問として 1 つ目に挙げられるのは、「過剰な負荷が原因でサイトがダウンしていることを検出するにはどうすればよいか」ですが、たいていは「CTO から連絡をもらう」という答えが返ってきます。他の人から連絡を受けた時点で Web サイトの問題に気付いても、適切な行動を取ることはできません。電話が鳴る前に、なんらかの計測結果に基づいて問題を認識できるようにする必要があります。その場合もだれかから連絡はありますが、少なくとも問題の発生を見越して、今までとは異なる受け答えをすることができます。CTO に「本当ですか」と応答しているようでは出世の見込みはありません。

次の疑問は、「まずだれに連絡すればよいか、だれが最初に行動を起こすのか」です。多くの場合、ネットワーク チームのメンバが最初に問題の兆候に気付きますが、比較的経験の浅いメンバである可能性もあるので、明確なエスカレーション計画が必要です。では、次はだれに連絡すればよいでしょうか。難しいのは、早めかつ迅速に診断を行い、どのような問題が発生しているかを把握することです。ネットワーク障害であれば自分たちで解決できるかもしれませんが、拡張に関する問題となると、話はまったく別です。この場合、早めに開発チームのメンバを招集するのが賢明です。

消火活動にかかわるメンバには十分な情報が必要なので、効率よく情報にアクセスできることは重要です。できる限り多くの情報を提供して、効果的な判断を可能にすることを目指します。これによって、解決が必要な問題の範囲を特定できるようになります。

唯一の解決策がコードを記述することである場合、コードを記述せず、それ以上の対応を施さないことがよくあります。もちろん問題が発生したことを記録し、今後の開発作業の優先順位付けに役立てることも重要ですが、山のようなコードを記述し、十分にテストせずにそれらを運用することは適切 (言い方を変えれば賢明) ではありません。消火活動で一番大事なのは、火がそれ以上燃え広がらないようにすることです。

拡張に関する問題が発生した場合、状況によっては単純に待機することが解決策になります。これも選択肢の 1 つとして考えてください。

同時に、このような不測の事態に備えることによって、実際に問題が発生したときにさまざまな技法を迅速に適用できるようになります。多くの場合、拡張に関する問題にネットワーク チームと開発チームが協力して取り組めば、非常に短い時間で問題を解決できます。企業で行っている宣伝活動を成功させることもできるでしょう。

結論を述べますが、ネットワーク チームから得られた教訓は、拡張性とパフォーマンスの高い ASP.NET アプリケーションを提供するには、アプリケーションを構築するメンバと、そのアプリケーションを展開および運用するメンバが緊密に協力する必要があることです。

必ずどこかの段階で共同作業を行うことになるので、早い段階でチーム間のミーティングを開いて情報を共有するに越したことはありません。このミーティングの目的は、アプリケーションの役割、しくみ、依存関係、負荷がかかったときの動作、時間の経過と共に発生する問題への対処方法など、アプリケーションのすべての要素について理解と同意を得ることです。

この共同作業を非常に効率よく行うことができれば、企業の敏捷性は向上します。つまり、発生した問題に迅速に対処し、将来の成功に向けてアプリケーションが必要とする要素に関する明確な目標を確立できるようになります。

Richard Campbell は、マイクロソフトの地域担当責任者であり、ASP.NET の MVP でもあります。また、.NET Rocks (dotnetrocks.com で公開されている .NET 開発者向けのインターネット オーディオ トークショー) の共同司会者も務めています。彼は数年にわたって企業を対象としたコンサルティング活動に従事しており、パフォーマンスと ASP.NET の拡張に関するアドバイスを行っています。さらに、彼は Strangeloop Networks の共同創立者でもあります。

© 2008 Microsoft Corporation and CMP Media, LLC. All rights reserved. 許可なしに一部または全体を複製することは禁止されています。