ASP.NETのWebアプリケーションで、
セッション情報にログインユーザーの情報を持たせておく、というのは
よく使う方法だと思います。
そういった場合、常にセッションが途切れないようにしなければなりませんが、
セッションの状態管理設定には、注意が必要です。
デフォルトでは、sessionStateのモードが、「InProc」です。
この設定は、アプリケーション内のプロセスに保持するため、最も高速です。
しかし、何ら障害に関する備えはないので、
アプリケーションのリスタートや、プロセスリサイクリング(ワーカープロセスの再作成)のタイミングで、
セッション情報が失われます。
よくあるのは、web.configの書き換えにより、アプリケーションのリスタートが行われることです。
この点は良く知られているので、「運用時はweb.configの書き換えなんてしないから大丈夫」と
判断され、「InProc」のままになってしまうことが多いと思います。
(高速な設定が望ましいとか、デフォルトから変更したくないとかの理由で)
ですが、本当に大丈夫なのでしょうか。
[問題点]
日経BP社刊『.NETエンタープライズ開発技術大全vol.3』によると、
アプリケーションのリスタートは、以下の場合に発生するそうです。
・大量のファイルが更新された場合
・仮想ディレクトリの接続パスが変更された場合
・web.configファイルが変更された場合(※前述)
・global.asaxファイルが変更された場合
・binディレクトリ内のファイルが変更された場合
これらの条件を満たした場合、セッション情報が失われることになります。
また、IIS6.0(Windows Server 2003)のプロセスリサイクリングにも注意が必要です。
デフォルトでは、プロセスリサイクリングが29時間ごとに発生しますので、
ちょうどリサイクリングのタイミングにかさなってしまうと、消滅することになります。
[解決策]
種々の設定に気を配り、絶対にアプリケーションリスタートもプロセスリサイクリングも大丈夫にする、
というのも一つの案だとは思いますが、
基本的には、「InProc」ではなく、「StateServer」や「SqlServer」へモード設定をしておくのが正しい対応策でしょう。
これらの設定であれば、アプリケーションのリスタート、プロセスリサイクリングによっても、
セッション情報が失われることはありません。
[注意点]
運用時に変更するのではなく、開発時から、設定を変更しておくべきだ、という点に注意してください。
というのも、シリアライズ不可のオブジェクトをセッションへ格納しようとした時に、
「InProc」の場合にはエラーが発生しませんが、
「SessionServer」や、「SQLServer」モードではエラーが発生するからです。
現実的な対応策として、開発時は、常に「StateServer」にしておき、
シリアライズが必要なオブジェクトに関しては、Serializable属性を予め付けておくようにしましょう。
※基本的な、DataSetなどは、最初からシリアライズ可能なので、独自にクラスを作成する場合に必要となります。
''' <summary>
'''セッション格納サンプルオブジェクト
''' </summary>
<Serializable()> _
Public Class SessionObjectSample
…… オブジェクトの内容 ……
End Class
運用時が「StateServer」であれ、「SqlServer」であれ、「InProc」であれ、
エラーとならないつくりにしておくことが大切です。
また、「StateServer」モードや「SqlServer」モードが
「InProc」よりも低速であることは事実なので、
セッション情報にあまりにも大量のデータを格納しないよう注意が必要です。
シリアライズ・デシリアライズによる負荷によっては、大変遅くなることも考えられます。
逆にいうと、格納するデータ量に注意すれば、
実際に問題となるほど遅くなることはないと思います。
運用時に発覚しないように、あらかじめ、設計・開発の時点から考えておく必要があります。
上記の点から、既に「InProc」で作成していて、運用が開始したアプリのセッションモードを変更するのは難しいかもしれません。
だからこそ、開発当初から、設定を変更しておくのが望ましいと思います。
安易に「高速だからInProc」ではなく、要件を満たした、最適な設定を検討しましょう。
コメント (1)
こんにちは。
件名【[ASP.NET] セッションのモード設定は「InProc」で良いのか?】について教えてください。
アプリケーションのリスタートとなる原因の一つに、
大量のファイルが更新された場合とありますが
ここで言うファイル更新とは、
フォルダ作成、ファイル作成、ファイルコピー、
フォルダ削除、ファイルの削除
の関わらず、大量(メモリー等の条件による)のファイル
更新が行われた時なのでしょうか?
現在、【フォルダ削除】時のみ、アプリケーションの
リスタートが発生し、フォルダ作成、ファイル作成、
ファイルコピー、ファイルの削除時は、リスタートは
発生していません。
フォルダ削除時のみ、アプリケーションのリスタートが
発生するとは言い切れないのでしょうか?
宜しくお願い致します。
>日経BP社刊『.NETエンタープライズ開発技術大全vol.3』
>によると、アプリケーションのリスタートは、以下の場合
>に発生するそう>です。
>
>・大量のファイルが更新された場合
>・仮想ディレクトリの接続パスが変更された場合
>・web.configファイルが変更された場合(※前述)
>・global.asaxファイルが変更された場合
>・binディレクトリ内のファイルが変更された場合
投稿者: taki | 2008年9月22日 20:01