ASP.NET Web アプリでセッション状態情報を格納する

完了

Web アプリで使用される HTTP プロトコルは、本質的にステートレスです。 多くの Web アプリでは、要求間で状態情報を保持し、それらの要求のコンテキストを提供する必要があります。 このコンテキストは、セッションと呼ばれます。 セッションの状態情報はさまざまな方法で保存できますが、いくつかの方法は他の方法よりも適切です。 どれが適切であるかは、Web アプリが実行されている環境によって異なります。

セッション状態を格納するためのオプション

セッションに依存する ASP.NET Web アプリでは、適切なセッション状態プロバイダーを使用することが重要です。 セッション状態プロバイダーは、各ユーザー セッションの状態を保持および保守する役割を担います。 Web アプリが、数十万もの同時ユーザーをサポートすることを目的としている場合、セッション状態プロバイダーは、ユーザーごとに個別のプライベート セッションをサポートする必要があります。

通常は、Web サーバーによってセッション情報が管理されます。 多くの場合、セッション データは、単なるキーと値のペアのコレクションです。 各セッションには、一意の識別子があります。

クライアントが Web アプリに接続して新しいセッションを開始すると、サーバーはセッション識別子を生成し、それを HTTP 応答メッセージの一部としてクライアントに渡します。 通常、この識別子は、クライアントの Web ブラウザーまたはクライアント アプリケーションが保存できる Cookie の形式で返されます。 後続のすべての要求には、この Cookie を要求の一部として含めることができるため、Web アプリは、各要求が属するセッションを認識できます。

Diagram showing the relationships between client apps, the web app running on the web server, and session state information identified by using cookies.

Web サーバー上では、セッション データをメモリ内、ディスク ファイル内、Azure テーブル ストレージなどの共有の場所内、または何らかの種類のデータベース内に格納できます。

セッション データをメモリ内に保持すると、アクセスは速くなりますが、水平スケーラビリティに影響があります。 Web アプリが、Web ファームとして、または複数リージョン デプロイの一部として機能する複数のサーバーによってホストされている場合、特定の Cookie を指定するクライアントからの要求はすべて、同じサーバーに送信される必要があります。 このような状況では、"スティッキー" セッションが発生します。

このレベルのクライアント/サーバーのアフィニティによって、一部のサーバーがオーバーロード状態になり、その他のサーバーの使用率が低下する可能性があります。 さらに、サーバーに障害が発生すると、状態情報は消失します。

セッション データをファイルに保存すると、セッション データが消失する可能性は低くなりますが、ファイルをサーバーのローカル ファイルに格納する場合は、同様の問題が発生する可能性があります。 この場合もクライアント/サーバーのアフィニティが問題になります。 Web サーバーに障害が発生すると、サーバーが復旧されるまでセッション状態情報を使用できなくなります。

最もスケーラブルな方法は、セッション データを、すべてのサーバーがアクセスできる共有データ ストアに書き込むことです。 この方法では、サーバー間での要求の負荷分散が改善されるだけでなく、個々の Web サーバーに障害が発生してもセッション状態の可用性が確保されます。

Azure を使用している場合、Table Storage、Azure SQL Database、または Azure Cache for Redis などのサービスを使用することができます。 Redis は、キーと値のペアを格納することを目的に設計され、高度に最適化されたキャッシュ サービスです。 Azure Cache for Redis は、セッションをメモリ内に格納するため、このようなオプションの中で最も高いパフォーマンスを発揮します。

ASP.NET Web アプリでのセッション状態プロバイダーの構成

セッション状態プロバイダーにより、ASP.NET Web アプリのセッション状態が管理されます。 セッション状態プロバイダーは、各クライアントのセッション データを整理し、セッション データの有効期間を処理し (セッションが期限切れになったら削除されるようにします)、プライバシーを維持します。 多くの場合、セッション データは暗号化され、異なるユーザー間で共有することはできません。

ASP.NET Web アプリでは、web.config ファイルの <sessionState> セクションを使用してセッション状態プロバイダーを構成できます。 <sessionState> タグにより、セッション プロバイダーが指定されます。 各プロバイダーは、その専用の <providers> セクション内で構成されます。このセクションにはプロバイダー固有の設定が含まれます。

ASP.NET の既定のセッション状態プロバイダーは、メモリ内で動作し、個別のプロバイダーを必要としません。 構成は次のようになります。

<configuration>
  ...
  <system.web>
    ...
    <sessionState mode="InProc" />
    ...
  </system.web>
  ...
</configuration>

別のプロバイダーを使用するには、<sessionState> 要素でモードを Custom に設定し、プロバイダーを含む NuGet パッケージを Web アプリに追加します。 次に、web.config ファイルの <sessionState> セクションを、そのプロバイダーを参照するように変更し、プロバイダーの設定を構成します。

次の例は、Azure Cosmos DB セッション状態プロバイダーの構成を示しています。 このプロバイダーでは、Cosmos DB データベース内のコンテナーにセッション データが書き込まれます。 データベースとコレクションを指定するには、databaseId および collectionId パラメーターを使用します。

<sessionState mode="Custom" customProvider="CosmosDBSessionStateProviderAsync">
  <providers>
    <add name="CosmosDBSessionStateProviderAsync" 
         cosmosDBEndPointSettingKey="[cosmosDBEndPointSetting]" 
         cosmosDBAuthKeySettingKey="[cosmosDBAuthKeySetting]" 
         databaseId="[DataBaseId]" 
         collectionId="[CollectionId]" 
         offerThroughput="5000" 
         connectionMode="Direct" 
         connectionProtocol="Tcp" 
         requestTimeout="5" 
         maxConnectionLimit="50" 
         maxRetryAttemptsOnThrottledRequests="10" 
         maxRetryWaitTimeInSeconds="10" 
         preferredLocations="" 
         partitionKey="" 
         partitionNumUsedByProvider="" 
         type="Microsoft.AspNet.SessionState.CosmosDBSessionStateProviderAsync, Microsoft.AspNet.SessionState.CosmosDBSessionStateProviderAsync, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </providers>
</sessionState>

Cosmos DB アカウントを事前に作成しておく必要があります。 エンドポイントのアドレスと認証キーは、cosmosDBEndPointSettingKey および cosmosDBAuthKeySettingKey パラメーターで指定します。

次の 2 つ目の例は、Azure Cache for Redis プロバイダーの構成を示しています。 この場合も、Azure Cache for Redis インスタンスが既に存在している必要があります。

<sessionState mode="Custom" customProvider="MySessionStateStore">
  <providers>
    <add name="MySessionStateStore"
         type="Microsoft.Web.Redis.RedisSessionStateProvider"
         host="[AzureCacheFirRedisEndpoint]"
         accessKey="[AccessKey]"
         ssl="true" />
  </providers>
</sessionState>

ホスト名の設定に使用するエンドポイント アドレスは、Azure portal 上で、このキャッシュの [概要] ページで確認できます。

Screenshot showing Azure Cache for Redis page in the Azure portal. The host name for the cache is highlighted.

AccessKey を、ポータル上の [アクセス キー] ページに一覧表示されるいずれかのキーとして指定します。

Screenshot showing the Access keys page for the cache in the Azure portal. The access keys are highlighted.

他にも、さまざまなテクノロジを使用してセッション状態情報を格納するプロバイダーが、Microsoft や取引先組織から数多く提供されています。

Note

セッション状態プロバイダーの選択は、アプリ コードに対して透過的です。 セッション状態プロバイダーを切り替えても、アプリケーションを変更する必要はありません。