「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>ASP.NET]]

* 目次 [#z629ff52]
#contents

*概要 [#ne6d30eb]
*はじめに [#efa3a83c]
**Webシステムの状態管理方式 [#t8b2d188]
2層C/Sシステムでは、クライアント側プログラムがDBに直接接続し、状態(UPが処理に必要とする一連の情報(制御情報や業務処理に必要な情報を含む))を一元管理するという方式が採用されている。これに対し3層C/SシステムやWebシステムでは、APサーバの拡張性・信頼性を確保するために、サーバの状態を保持しないで「サーバへのリクエスト」・「クライアントへのレスポンス」の間で必要な情報を持ち回り、サーバがリクエストを受け付けたときサーバ側で状態を復元するという方式が一般化した(一般的に、サーバに状態を保持しないほうが拡張性は高くなる(サーバに状態を保持した場合、信頼性を確保するための冗長化構成が組み難いなどの問題があるため))。しかし、近年のWebシステムにおいては、サーバに状態を保持した場合も拡張性・信頼性を確保するための技術([[Session>ASP.NET Session]]情報をリモート プロセス・リモート サーバなどで一元管理するためのインフラス トラクチャの構築技術)も登場しており、サーバ側のメモリ領域にユーザ毎に確保される「[[Session>ASP.NET Session]]」を使用して、状態を保持するケースが多数を占めるようになってきている。このため、3層C/SシステムやWebシステムの「状態管理方式」の大枠は、次の2つの方式に分けることができる。

表1:3層C/SシステムやWebシステムの状態管理方式

|項番|状態管理方式|説明|h
|1|サーバ ステートレス|サーバ側の状態保持領域を利用しない。|
|2|サーバ ステートフル|サーバ側の状態保持領域を利用する。|

特にWebシステムの「状態管理方式」は、クライアント側で状態を一元管理することができないため、クライアント側とサーバ側の双方で連携して状態を管理する必要があり、2層・3層C/Sアプリケーションと比べて複雑である。このため、本ドキュメントではWebアプリケーション用のAPサーバであるASP.NETを使用したASP.NETアプリケーションの「状態管理方式」に関する、下記の項目について説明する。

-ASP.NETアプリケーションの一般的な「状態管理方式」
-ASP.NETアプリケーションの開発で使用可能な「状態管理技術」
--実装上の考慮点
--性能の考慮点
-拡張性・信頼性を確保するための、負荷分散(冗長化)構成を組む際の考慮点

特に、「状態管理方式」の選択や「状態管理技術」の使い方を誤れば、性能の悪化や保守性の悪化、予期せぬセキュリティ問題が発生したり、拡張性・信頼性の要件が満たせないという問題などにも結びついたりするので注意が必要である。

*Webアプリケーションの状態管理方式 [#g8bb301d]
**サーバ ステートレスな状態管理方式 [#n0fdac0c]
「サーバ ステートレスな状態管理方式」とはWeb・APサーバに状態を持たせない方式であり、必要なデータはDBサーバ上に永続化するか、クライアント・サーバ間でHTTPのリクエスト ⇒ レスポンス ⇒ リクエストと状態を持ち廻る方式である。この場合、サーバはリクエストを処理してレスポンスを返した段階でWeb・APサーバ上のメモリの情報を破棄し、Web・APサーバ上に状態を保持しない。

#ref(1_ServerStatelessStateManagementSystem.png,left,nowrap,サーバ ステートレスな状態管理方式)

表:サーバ ステートレスな状態管理方式の処理概要
|順番|>|処理の実装箇所|処理|h
|~|クライアント / サーバ|モジュール|~|h
|1|クライアント側|wwwブラウザ|「サーバ処理1」に対して「ページ1」を要求する。|
|2|サーバ側|サーバ処理1|「ページ1」のHTMLをクライアントに出力する。|
|3|クライアント側|wwwブラウザ&br;ページ1|「Form」や「クエリー ストリング」に処理を継続するために必要な情報を含め「サーバ処理2」を要求する。|
|4|サーバ側|サーバ処理2,3|「サーバ処理2」 ⇒ 「サーバ処理3」と情報を持ち廻る時は、「Form」・「HTTP Context」などに情報を格納した後にサーバ処理を遷移し、「ページ2」のHTMLをクライアントに出力する。|

**サーバ ステートフルな状態管理方式 [#zc19500c]
「サーバ ステートフルな状態管理方式」とはWeb・APサーバに状態を持たせる方式であり、必要なデータをWeb・APサーバ上のメモリ領域に保持する。

#ref(2_ServerStatefulStateManagementSystem.png,left,nowrap,サーバ ステートフルな状態管理方式)

この方式では、Web・APサーバ上のメモリ領域に状態を保持する(主に[[Session>ASP.NET Session]]が使用される)。このため、保持すべきデータをDBサーバ上に永続化したり、クライアント・サーバ間で状態を持ち廻ったりしなくても、画面間で情報を引き継ぐことができる。また、「サーバ ステートレスな状態管理方式」で使用した技術も併用できる。

**ASP.NETにおける状態管理技術 [#r11f795a]
以下の表に、
-サーバ ステートレスな状態管理方式
-サーバ ステートフルな状態管理方式
で使用できるASP.NETにおける状態管理技術についてまとめた。

表:ASP.NETにおける状態管理技術の説明
|項番|状態管理技術|説明|
|1|Formデータ|HTTPのメッセージ ボディを使用する。送信時はFormのポストで送信する。受信時はHTMLとして受信する。|
|2|ViewState|Hiddenを仕様した状態保持の仕組みだが、ASP.NETの独自の基盤機能が付加されている。|
|3|Query string|HTTPのリクエストのメッセージ ヘッダーを使用する。|
|4|Cookie|HTTPのメッセージ ヘッダーを使用する。|
|5|Server.Transfer+HTTP Context領域|Server.Transfer処理はサーバ処理を遷移するためのメソッド、HTTP Context領域はリクエスト単位で確保する領域である。&br;ASP.NET独自の呼称だが、類似した技術が、似たような仕組みは各APサーバにも用意されている。|
|6|[[Session>ASP.NET Session]]|ASP.NETの組込みオブジェクト。Webアプリケーションで一般的に使用されるが、ASP.NETの独自の基盤機能が付加されている。|
|7|Application|ASP.NETの組込みオブジェクト。アプリケーション単位の共通情報を管理する。|
|8|静的変数|ASP.NETプログラムのグローバル変数。|
|9|Cache|ASP.NETの組込みオブジェクト。キャッシュ処理用に使用される。|

表:ASP.NETにおける状態管理技術の特徴
|項番|状態管理技術|>|>|>|区分|
|~|~|ASP.NET独自|Webアプリケーション一般|ステートレス|ステートフル|
|1|Formデータ|-|○|○|-|
|2|ViewState|○|-|○|-|
|3|Query string|-|○|○|-|
|4|Cookie|-|○|○|-|
|5|Server.Transfer+HTTP Context領域|-|○|○|-|
|6|[[Session>ASP.NET Session]]|○|-|-|○|
|7|Application|○|-|-|○|
|8|静的変数|-|○|-|○|
|9|Cache|○|-|-|○|

*ASP.NETの特徴 [#a5f26a81]
ASP.NETが、今までのWeb開発技術から大きく進化した点に、VB6.0以前のバージョンや.NETのWindowsアプリケーションなどで知られている「イベント ドリブンのプログラミング モデル」が採用された点が挙げられる。この「イベント ドリブンのプログラミング モデル」を可能にしたことで、ASP.NETでは、「同一の画面に対してポストバックする方式」が標準となった。

**ポストバックとは [#wbe1f45c]
「同一の画面に対してポストバックする方式」とは、自身を生成した画面(aspx)に対してForm情報をポストする方式のことであり、ASP.NETのアプリケーションは通常、以下のように動作する。

#ref(3_PostbackOfASPdotNET.png,left,nowrap,ASP.NETのポストバック)

ASP.NETでは、画面上でボタンを押すと自分の画面に対して「Form情報」が「ポストバック」される。サーバ側では、画面上のどのボタンが押されたのかを「Form情報」から自動的に解析し、画面に登録されているイベント ハンドラに自動的に処理を振り分ける。このように、従来の技術と比べASP.NETでは「動的ページ」と「サーバ処理」の関係が、「画面」という単位でわかりやすく対応付くようになった。また、従来の技術では同一画面を再表示する場合、ポストされた「Form情報」をサーバ側で再取得して、再びHTMLの各要素のvalueに設定して出力する必要があったが、ASP.NETのWebコントロール(以下、Webコントロールと略す)では、Webコントロールの情報をサーバ側で復元する処理も自動化されている。

**ViewStateとは [#pf52f6da]
ASP.NET独自のサーバ ステートレスな状態管理技術として「ViewState」がある。ココでは、この「ViewState」がどの様な技術で実装され、どの様な目的で使用されているかについて説明する。

-「ViewState」の実装~
初めに、「ViewState」がどの様な技術で実装されているかについて説明する。~
「ViewState」は、
++レスポンス時に「ViewState」に設定されたオブジェクトをシリアライズし、これにハッシュ値を付与したデータを~
base64エンコードして、name属性="__VIEWSTATE"、id属性="__VIEWSTATE"に設定されたHiddenタグに保存する。
++リクエスト時は、逆の操作でname属性="__VIEWSTATE"、id属性="__VIEWSTATE"に設定されたHiddenタグのデータを~
base64デコードし、ハッシュ値を検証した後にデータをデシリアライズしてオブジェクトとして復元する。

という実装になっている。

ハッシュ値の付与や、base64エンコードを除けば 、オブジェクトのデータをシリアライズ・デシリアライズし、Hiddenタグを使用して文字列形式で情報を保持しているだけである。このため、「ViewState」はサーバ ステートレスな状態管理技術に分類できる(設定によっては暗号化も可能であるが、デフォルトの設定では暗号化されないので注意が必要である)。

-「ViewState」の利用目的~
「ViewState」の利用目的には、次の2種類がある。

--イベント ドリブンのプログラミング モデルを可能にしたASP.NETのアプリケーション基盤技術としての利用
--同一画面内でのみ機能する(画面間を跨った利用は不可能)、サーバ ステートレスな状態管理技術としての利用

次項では、「ViewState」の利用目的の詳細について説明する。

***ViewStateを使用したアプリケーション基盤処理 [#u87da815]
「ViewState」には、イベント ドリブンのプログラミング モデルを実現するための使用方法が存在する。この用途では、利用者から意図することなく利用される。この用途とは、Webコントロールに関する表示状態の情報をViewStateに保存することで「ポストバック」の際に、

-Webコントロールの情報を、サーバ側で復元する。通常のテキスト ボックスなどのWebコントロールのデータは、「ViewState」をOFFにしても復元されるが、グリッド ビュー コントロールなどのWebコントロールにデータ バインドしたデータは、「ViewState」をOFFにした場合、復元されなくなる。
-クライアント側で何が行われたのかをサーバ側で自動解析し、Webコントロールのchangeイベント ハンドラ に自動的に処理を振り分けるなど。Webコントロール毎にイベント名が異なるが、TextBoxコントロールにはTextChangeイベント、ListBoxコントロールにはSelectedIndexChangedイベントなどがある。

といった用途である。

#ref(4_ApplicationFoundationProcessingUsingTheViewState.png,left,nowrap,ViewStateを使用したアプリケーション基盤処理)

***ViewStateを使用したサーバ ステートレスな状態管理 [#q137fce3]
前項に示した「ViewState」の使用方法以外には、同一画面内でのみ機能する(画面間を跨った利用は不可能)、サーバ ステートレスな状態管理技術としての使用方法がある。この使用方法では、利用者が必要に応じてアプリケーションに実装する。この使用方法は、独自に「Hiddenタグ」を追加して、そこにシリアル化されたオブジェクト情報を保持する方式と大きな違いは無い。

Webフォームのメンバ変数は、Windowsフォーム内のメンバ変数のように情報を保持しない。また、サーバ ステートレスな状態管理方式を採用している場合、サーバ側のメモリも利用できない。このような場合に「ViewState」を使用すれば、同一画面内でのみ状態を保持することができる。このため、見方によってはWebフォーム内の情報を保持する機構と解釈することもできる。

#ref(5_MechanismForHoldingTheInformationInTheWebForm.png,left,nowrap,WindowsForms内のメンバ変数のように、Webフォーム内の情報を保持する機構)

また、サーバ ステートフルな状態管理方式を採用している場合、Webフォーム内の情報を保持する処理を「Session」でも代替できるが、「ViewState」の場合はデータ消去の手間がかからないというメリットがある。

***ViewStateでできること。 [#j831db84]
以下の様なことができるもよう。

-独自の値を追加する、Base64デコードして値を確認する。
-[[EnableViewState>https://msdn.microsoft.com/ja-jp/library/system.web.ui.page.enableviewstate.aspx]]で有効/無効の制御。
-なお、暗号化には署名と暗号化があり、双方ともON/OFFが可能であるもよう。
--[[EnableViewStateMac>https://msdn.microsoft.com/ja-jp/library/system.web.ui.page.enableviewstatemac.aspx]]
--[[ViewStateEncryptionMode>https://msdn.microsoft.com/ja-jp/library/system.web.ui.page.viewstateencryptionmode.aspx]]

-参考
--iPentec
---[C#] ViewStateに独自の値を保存する~
https://www.ipentec.com/document/document.aspx?page=csharp-asp-net-save-original-value-in-viewstate
---[C#] ViewStateの値の文字列をデコードして解析する~
https://www.ipentec.com/document/document.aspx?page=csharp-asp-net-viewstaet-decode

---[C#] ASP.NETのViewStateを無効にする~
https://www.ipentec.com/document/document.aspx?page=csharp-asp-net-disabled-viewstate

---[C#] ViewStateModeの違いによる動作の違い~
https://www.ipentec.com/document/document.aspx?page=csharp-aspnet-viewstatemode
---[ASP.NET] ASP.NETのViewState値の文字列の暗号化を無効にする~
https://www.ipentec.com/document/document.aspx?page=asp-net-viewstate-value-crypt-disabled

**ViewStateの使用上の注意点 [#le7839e3]
***アプリケーション基盤処理の注意点(事例) [#f7675d3a]
「ViewState」を利用する際、最も注意しなければならない点は、「クライアント側にダウンロードされるHTMLデータが膨張し、ネットワーク トラフィックが増加して性能劣化に繋がる可能性がある」という点である。

繰り返すが、「ViewState」は、イベント ドリブンのプログラミング モデルを可能にするASP.NETのアプリケーション基盤技術である。このため、意図的に利用していなくても、WebフォームがHTMLを出力する際に影ながら利用されてしまう。

このため、場合によっては無駄なHTMLデータが大量に出力されることになる。

例えば、読み取り専用のグリッド ビュー コントロールに表示データをデータ バインドし、クライアントに出力したとする。すると、ASP.NETの基盤処理により、自動的にデータ グリッド コントロールの表示状態の情報を「ViewState」に出力してしまう。

ある事例では、1MBのHTMLテーブル データに対し1MBの「ViewState」が出力され、必要な表示データが1MBなのに対し、実際にクライアント側にダウンロードされるHTMLデータが2倍の2MBに膨れ上がり、ネットワーク トラフィックが増加して性能劣化に繋がった。

#ref(6_UnnecessaryViewStateDataExpandDataAndIncreaseNetworkTraffic.png,left,nowrap,不要な「ViewState」データによるデータの膨張とネットワーク・トラフィックの増加)

この事例のグリッド ビュー コントロールは読み取り専用であったため、changeイベント ハンドラなどへの振り分けは必要なかった。

この事例での適切な対策としては、グリッド ビュー コントロールの「ViewState」機能を無効に設定し、DB上のデータを再度取得するなどの方式が挙げられる。

***ViewStateを使用してデータを保持する場合の注意点(事例) [#f066a58b]
「ViewState」を、Webフォーム内の情報を保持する機構として利用した場合も、大容量のデータを「ViewState」に保持した場合は、クライアント側にダウンロードされるHTMLデータが膨張しネットワーク トラフィックが増加して性能劣化に繋がる。

ある事例では、ドロップ ダウン リスト コントロールなどにデータ バインドするマスタ データのDataSetオブジェクトやDataTableオブジェクトなどを「ViewState」に保存して、HTMLデータが膨張しネットワーク トラフィックが増加して性能劣化に繋がった。

この事例での適切な対策としては、DB上のデータを再度取得したり、「[[Session>ASP.NET Session]]」・「Cache」に格納した情報を利用したりする方式が挙げられる。

***ViewStateの使用上の注意点まとめ [#i814b137]
本項では、「ViewState」の使用上の注意点をまとめる。

「ViewState」のデータ自体は、ただの「Hiddenデータ」として埋め込まれることを意識し、「ViewState」を使用する際にはクライアント側にダウンロードされるHTMLデータが膨張し、ネットワーク トラフィックが増加して性能劣化に繋がることがないように注意を払う。

データを「ViewState」に保持するより、DB上のデータを再度取得するか「Session」に格納した情報を利用する方が、処理効率は良い可能性がある。また、DB上のデータを再度取得するオーバーヘッドが問題となる場合で、データがマスタ データであれば、「Cache」を使用しても良い。

特に、ADO.NETのDataSetオブジェクトやDataTableオブジェクトなどをデータ バインド可能なWebコントロールが出力する「ViewState」は、巨大になる傾向がある。以下にデータ バインド可能なWebコントロールを列挙しておく。
-GridView、Repeater、ListBox
-CheckBoxList、Radiobuttonlist
-DropDownList

また、
-Webコントロールの情報を、サーバ側で復元する。
-クライアント側で何が行われたのかをサーバ側で自動解析し、
Webコントロールのchangeイベント ハンドラなどに自動的に処理を振り分ける。

などの処理がそもそも不要なWebコントロールに対しては、「ViewState」の機能を停止し(Webコントロールの「ViewState」の機能を停止させたい場合は、該当するWebコントロール「EnableViewState」プロパティをfalseに設定する。)、クライアント側にダウンロードされるHTMLデータの膨張を抑止することも検討する。

*状態管理技術の特徴 [#zbd6e242]
ココでは、状態管理技術の特徴を解説する。

**サーバ ステートレスな状態管理技術の共通的な特徴 [#md584ddd]
以下、サーバ ステートレスな状態管理技術の共通的な特徴を簡単に説明する。


-サーバにデータを保持しないことによるメリット~
サーバ ステートレスな状態管理技術は、サーバにデータを保持しない。このため、次に示すメリットが考えられる。
--サーバ リソースの消費量が少なく、拡張性に優れる。
--サーバ リソース(メモリ)の領域計算が容易である。
--サーバ リソース(メモリ)の解放タイミング(タイムアウトを含む)を考慮する必要がない。
--拡張性・信頼性を確保するための、負荷分散(冗長化)構成が容易である。

-クライアントにデータがダウンロードされることによるデメリット~
サーバ ステートレスな状態管理技術は、クライアントにデータがダウンロードされる。このため、次に示すデメリットが考えられる。
--ネットワーク トラフィックが問題になる。
--持ち回りデータの改竄が可能なため、セキュリティを確保するのに都合が悪いことがある。

-プログラミングの難易度~
サーバ ステートレスな状態管理技術を使用した場合のプログラミングの難易度は、下記のように評価できる。
--必要なデータの引継ぎ処理に関する設計・実装が多くなる。
--「Server.Transfer処理とHTTP Context領域の組合せ」などのASP.NETの標準的な画面遷移方法以外の、新規ウィンドウ オープンやURL直打ちなどの特殊な操作に対応することが比較的容易である。

**サーバ ステートフルな状態管理技術の共通的な特徴 [#n364efff]
以下、サーバ ステートフルな状態管理技術の共通的な特徴を簡単に説明する。


-クライアントにデータがダウンロードされないことによるメリット~
サーバ ステートフルな状態管理技術は、クライアントにデータがダウンロードされない。このため、次に示すメリットが考えられる。
--ネットワーク トラフィックを軽減できる。
--データを持ち回る必要がなく、改竄のリスクが無いため、セキュリティを確保するのに都合が良い。

-サーバにデータを保持することによるデメリット~
サーバ ステートフルな状態管理技術は、サーバにデータを保持する。このため、次に示すデメリットが考えられる。
--サーバ リソースの消費量が多いため、拡張性に乏しい。
--サーバ リソース(メモリ)が枯渇しないように、領域計算が必要になる。
--サーバ リソース(メモリ)の解放タイミング(タイムアウトを含む)を考慮する必要がある。
--拡張性・信頼性を確保するための、負荷分散(冗長化)構成を工夫する必要がある。

-プログラミングの難易度~
サーバ ステートフルな状態管理技術を使用した場合のプログラミングの難易度は、下記のように評価できる。
--必要なデータの引継ぎ処理に関する実装が少なくて済む。
--特殊な画面遷移に対応する必要がある場合、ユーザ プログラムで[[Session>ASP.NET Session]]内の状態を判定し、処理を振り分けるなどして、これらに対応できるように設計する必要がある。

**個別の「状態管理技術」の特徴 [#w23e807f]
ココでは、個別の「状態管理技術」の特徴を解説する。

***Session [#p3907808]
サーバ ステートフルな状態管理技術なので、「[[サーバ ステートフルな状態管理技術の共通的な特徴>#n364efff]]」に示した特徴を持つ。クライアントのブラウザがWebサーバに接続したタイミングで、サーバがクライアントに返す「SessionID(基本的にCookieを利用)」を利用することにより、それ以降の接続でユーザの[[Session>ASP.NET Session]]を識別できるようになり、Webサーバ上のメモリ上にユーザ毎の「Session」を使用できる。仕組みは上記に示した簡単なものであるが、利用する際は、更に以下の点を考慮すると良い。

-長所~
--画面を跨って状態を管理する「状態管理技術」の中では最も手軽に利用できる。また、APIからも非常に簡単に使用することができる。
--「Cookie」が利用できない環境でも、Cookie-less sessionを使用すれば、「Session」を使用できる。Cookie-less sessionではURLに「SessionID」が追加される。

-短所~
--基本的には、シリアル化ができないオブジェクトも格納できるが、ステート サービス・ステート データベース(後述)を使用する場合は、シリアル化可能なオブジェクトしか格納することができなくなるので、拡張性を確保する必要があるならば、シリアル化可能なオブジェクトのみ格納する。
--以下の式により、[1台のWebサーバ上で使用される[[Session>ASP.NET Session]]領域の容量] を計算し、他のサービスなどが使用するメモリなども考慮した上で、メモリ使用量が許容量以下 に抑えられるよう計算して使用する必要がある。~
~
[ユーザ1人あたりが使用する[[Session>ASP.NET Session]]領域の容量] × [1台のWebサーバが処理するユーザ数]
= [1台のWebサーバ上で使用される[[Session>ASP.NET Session]]領域の容量]

--メモリ使用量の許容量
---サーバの物理メモリの使用量としては90%以下であるが、32bit環境では、ASP.NETの.NET Frameworkが使用できる仮想メモリ量は別に決められているため、[1台のWebサーバ上で使用されるSession領域の容量]は、これ以下の使用量である必要がある。

---ASP.NETの.NET Frameworkが使用できるメモリ量は、.NETの設定にあるMemoryLimit要素で指定される。この要素のデフォルト値は60%(サーバの物理メモリ容量の60%を意味する)となっており、サーバの物理メモリ容量が4GBである場合、ASP.NETのアプリケーションが使用できるデフォルトの仮想メモリ量は、4GB × 0.6 = 2.4GBとなる。

---このため、物理メモリ容量が大きいサーバでは、ASP.NETのアプリケーションの使用できる仮想メモリ量が、ASP.NETのワーカ プロセスの仮想アドレス空間の上限に近づく(若しくは上回る)ことがあるので注意する。一般的な環境のユーザ モードの仮想アドレス空間の上限は2GBである。

---参考:MSDNライブラリ > .NET Frameworkクラス ライブラリ~
'> System.Web.Configuration.ProcessModelSection.ProcessModelSection.MemoryLimitプロパティ~
http://msdn.microsoft.com/ja-jp/library/system.web.configuration.processmodelsection.memorylimit.aspx

***Application、静的変数 [#v3205753]
サーバ ステートフルな状態管理技術なので、「[[サーバ ステートフルな状態管理技術の共通的な特徴>#n364efff]]」に示した特徴を持つ。

-長所
--アプリケーションで共有されるデータを効率よく保存できる。
--採番テーブルの採番プール化などに役立つ。

-短所
--排他制御が必要になり、使い難い(再現性の低いバグを造り込み易い)。
--ネットワーク負荷分散(冗長化)の構成ノードで共有する仕組みがない。

***Cache [#y5135a45]
サーバ ステートフルな状態管理技術なので、「[[サーバ ステートフルな状態管理技術の共通的な特徴>#n364efff]]」に示した特徴を持ち、更に「Application」にキャッシングに必要なアプリケーション基盤機能を実装したような特徴を持っている。

-長所
--キャッシングに必要なアプリケーション基盤機能が実装されている。
--メモリ不足を自動検出して、データを破棄する機能を持つ。
--日付情報から自動的にデータを破棄する機能を持つ。
--ファイルの書き換えを自動検出し、自動的にデータを破棄する機能を持つ。
--他のオブジェクトの書き換えを自動検出し、自動的にデータを破棄する機能を持つ。

--性能や拡張性の向上を実現できる(「Cache」は、サーバ側の状態管理技術であるが、負荷分散(冗長化)構成を組む際の問題とはならない)。

-短所
--排他制御が必要になり、使い難い(再現性の低いバグを造り込み易い)。
--主に常数データに利用する。更新されるデータの保持には向かない。

--実装に熟練した技術者が必要になる。
---利用前に、nullチェックが必要。
---長所に列挙した機能自体を使いこなすことが難しい。
---キャッシュ データを構築する処理を1スレッドにして排他を掛ける必要がある。
 
***ViewState [#l865dbc6]
サーバ ステートレスな状態管理技術なので、「[[サーバ ステートレスな状態管理技術の共通的な特徴>#md584ddd]]」に示した特徴を持つ。また、多くは「[[ViewStateを使用してデータを保持する場合の注意点(事例)>#f066a58b]]」、「[[ViewStateの使用上の注意点まとめ>#i814b137]]」で説明済みである。

-長所
---APIから非常に簡単に使用できる。
---ハッシュを使用した改ざん防止機能がある。
-短所
---ASP.NETは、「同一の画面に対してポストバックする方式」を採用しているため、そもそもFormデータ(Hidden項目を含む)を次画面に情報を引き継げない。
---また、ASP.NET2.0で、クロスページ ポストバックにより、Webコントロールの情報の「一部」を別ページに引き継ぐこともできるようになったが、「ViewState」によるWebコントロールの復元はされない。「ViewState」も解読できない。
---デフォルトでは暗号化されず、base64エンコードをデコードすれば解読可能。プロパティの設定を変更すれば暗号化可能になる。
---「ViewState」に格納したデータはbase64エンコード後のテキスト・データとしてHiddenタグに保存されるため、バイト配列化するためにシリアル化可能なオブジェクトしか格納することができない。

***Cookie [#b20d90e9]
サーバ ステートレスな状態管理技術なので、「[[サーバ ステートレスな状態管理技術の共通的な特徴>#md584ddd]]」に示した特徴を持ち、また、主に固定データの持ち廻りに使用される(更新用のAPIも用意されているため、可変データの持ち廻りも可能である)。

このため、アプリケーション基盤技術である、
-ユーザ毎の「Session」を識別するための「SessionID」
-認証基盤が発行する「認証チケット」

などの情報を持ち廻る用途にも利用されている。

それ以外に、パーソナライズ状態の維持(ログインされていない状態でも、ユーザを識別した状態で画面を表示するなどの機能のこと。これによりサイトの利便性を向上させることができる)という用途にも使用される。

*負荷分散(冗長化)構成と状態管理方式 [#kdae6e2b]
拡張性・信頼性を確保するために、負荷分散(冗長化)構成をとるケースがある 。

#ref(7_ToEnsureTheScalabilityAndReliabilityOfWindowsServerExampleLoadBalancingStructure.png,left,nowrap,Windows Serverの拡張性・信頼性を確保するための、負荷分散(冗長化)構成例)

クライアント リクエストは、NLB (あるいは負荷分散ハードウェア、DNSラウンドロビン)を用いて各ノード(Webサーバ)に分散される。

この場合、クライアント リクエストを別のノードへ振り替えられるようにするため 、各ノードは通常サーバ ステートレスである。特定のノードに障害が発生した場合やメンテナンスのためにサービスを中断する必要がある場合、クライアント リクエストは自動的に別のノードへと振り替えられる。

バックエンド データ層は、MSCS 上にホストする。障害が発生した場合やメンテナンスのためにサービスを中断する必要がある場合、正常なノードがデータへのアクセスを提供し続ける。

ネットワーク負荷分散(冗長化)構成をとる場合、「状態管理技術」である、Session、ViewState、Cookie(Forms認証(暗号化されたCookie認証チケットを使用するカスタム認証の実装を支援するASP.NETの基盤機能))を正しく利用するに当たって、サーバの構築・設定に特別な配慮が必要になる。

ココでは、このサーバの構築・設定のポイントについて説明する。

**負荷分散(冗長化)構成とSession [#nab90cd2]
デフォルトの「[[Session>ASP.NET Session]]」の設定では、asp.netのホストプロセスの使用する仮想メモリにデータを格納する。このため、ネットワーク負荷分散(冗長化)構成を組み「[[Session>ASP.NET Session]]」などの、各ノードのインプロセスのメモリ領域を使用する場合 、同一クライアントからの要求は、特定のノードへ割り当てる必要がある。

これは、クライアント リクエストがノードを跨いだ場合、各ノードの同期のとれていないSessionを使用してしまうためである。このため、同一クライアントからの要求は、特定のノードへ割り当てる必要がある。NLBクラスタの場合、Affinityパラメタを「単一モード」に設定することで、同じクライアント(IPアドレス)から発信された全てのTCP接続を、クラスタ内の特定の「物理サーバ」に送ることができる。

#ref(8_SessionOfTheCaseThatUsingNLB.png,left,nowrap,Windows ネットワーク負荷分散した場合のSession)

***ステート サービス・ステート データベースの導入 [#y6d2607f]
「負荷分散(冗長化)構成とSession>#nab90cd2]]」に示した問題を回避するために、ASP.NETでは「[[Session>ASP.NET Session]]」の永続化の専用システム(ステート サービス・ステート データベースと呼ばれる)を使用して、プログラムから意識することなくネットワーク負荷分散(冗長化)の構成ノード共通の「[[Session>ASP.NET Session]]」に状態を永続化するインフラの構築が可能である。

ステート サービス・ステート データベースの特徴については以下の表にまとめる。

表ステート サービス・ステート データベースの特徴
|項番|状態管理技術|説明|h
|1|ステート サービス|Windowsサービスのプロセス上に「[[Session>ASP.NET Session]]」のデータを格納する方式である。一般的には、専用サーバにステート サービスを持たせる。|
|2|ステート データベース|SQL Serverのストレージ上に「[[Session>ASP.NET Session]]」のデータを格納する方式である。この場合、専用サーバにステート データベースを持たせる。|

ステート サービス・ステート データベースを導入した場合、どのノードからも「クライアントa」に対する「[[Session>ASP.NET Session]]-a」が取得可能になる。この構成では、同一クライアントからの要求を、同一のWebサーバへ割り当てる必要はない。このため、ラウンドロビンなど、動的な振り分けにも対応可能になる。


#ref(9_SessionOfTheCaseThatIntroducingStateServiceAndStateDatabase.png,left,nowrap,ステート サービス・ステート データベースを導入した場合のSession)

***ステート サービス・ステート データベースの導入と、信頼性の関係 [#sa264f5b]
ステート サービス・ステート データベースを利用すると、ネットワーク負荷分散(冗長化)構成を組み「[[Session>ASP.NET Session]]」を使用する場合も、同一クライアントからの要求を、特定のノードへ割り当てる必要がなくなる。

また、あるノードで障害が発生して、ネットワーク負荷分散(冗長化)の構成ノードから切り離されても、ユーザは、「[[Session>ASP.NET Session]]」の情報を消失せずに、処理を続行できる。

これにより、Webアプリケーションの信頼性が向上する 。

#ref(10_SeparateTheConstituteNodeOfLoadBalancingInTheEventOfFailure.png,left,nowrap,障害発生時、負荷分散(冗長化)構成ノードを切り離す)

ただし、ネットワーク負荷分散(冗長化)構成で、ステート サービス・ステート データベースを利用した場合、そこが「単一障害点」になる可能性があるので注意が必要になる。「単一障害点」を回避するための方法は、ステート データベースで使用するSQL ServerをMSCS、若しくはSQL Server 2005 SP1で実装されたデータベース ミラーリング機能でクラスタリングすることである。これにより、「単一障害点」がなくなる。

上記の施策で「単一障害点」を回避できるが、「単一障害点」を回避して信頼性を向上させるだけのために、ステート データベースで使用するSQL ServerのMSCS構成を新規導入するのは、技術的・予算的に難しい場合が多い。

このような場合は、下記の折衷案を検討するべきである。

-ネットワーク負荷分散(冗長化)の構成を、同一クライアントからの要求は特定のノードへ割り当てるように構成し、ノードで障害が発生した際「[[Session>ASP.NET Session]]」に保存したデータの消失を許容する(この場合、業務を再実行する必要がある)。

-「単一障害点」であるステート サービス・ステート データベースの復旧を迅速に行う前提で、「単一障害点」を許容する。

-サーバ ステートレスな設計に変更し、ネットワーク負荷分散(冗長化)の構成ノードがサーバ側の「状態管理技術」を使用しなくて済むようにする。


補足:障害発生時の「Session」の引継ぎはMSCS構成でも不可能であるため、「Session」を他ノードに引き継ぐ場合はMSCS構成ではなく、必ずネットワーク負荷分散(冗長化)構成と、ステート サービス・ステート データベースを構成する必要がある。これは、MSCSがサーバのメモリ状態をフェイル オーバーする機能を備えていない為である。MSCSでは、共有ディスク上の状態データのみ引き継ぐことができる。

**負荷分散(冗長化)構成とデータの暗号化・検証 [#v0f39ab2]
ステート サービス・ステート データベースに保存される「Session」データ、Hiddenタグに出力される「ViewState」データ、Forms認証の基盤機能を使用した場合に発行される「Cookie認証チケット」は、各ノードの.NETの設定にあるmachineKey要素の情報で暗号化・検証される 。

このため、ネットワーク負荷分散(冗長化)構成を組み、以下の条件に当該する場合は、machineKey要素をネットワーク負荷分散(冗長化)の構成ノード全体で統一しておく必要がある。

-ネットワーク負荷分散(冗長化)構成に於いて、同一クライアントからの要求を、特定のノードへ割り当てない設定で運用する必要がある。
-あるノードで障害が発生して、ネットワーク負荷分散(冗長化)の構成ノードから切り離されても、処理を続行する必要がある。

machineKey要素をネットワーク負荷分散(冗長化)の構成ノード全体で統一することにより、クライアントのリクエストが別のノードに振り分けられた場合でも、暗号化された「Session」・「ViewState」・「Cookie認証チケット」を復号化・検証できるようになり、処理を続行できる。

#ref(添付用1/11_UnifiedTheMachineKeyElementInTheOverallConstituteNodeOfLoadBalancing.png,left,nowrap,machineKey要素を負荷分散の構成ノード全体で統一)

-MSDNライブラリ > .NET Frameworkの全般リファレンス > machineKey要素 (ASP.NET設定スキーマ)~
http://msdn.microsoft.com/ja-jp/library/w8h3skw9.aspx

----
Tags: [[:.NET開発]], [[:ASP.NET]], [[:ASP.NET Web Forms]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS