23 ASP.NETセッション状態の管理

Coherenceセッション・プロバイダを使用して、Coherenceクラスタ内のASP.NETのセッション状態を管理できます。Coherenceセッション・ストアは、Coherence .NET拡張クライアントを使用して、ASP.NETセッションをCoherenceキャッシュに格納します。

この章の内容は次のとおりです。

ASP.NETセッション状態の概要

Coherence for .NETを使用すると、ASP.NETセッション状態をCoherenceクラスタに格納および管理できます。これには、Microsoftが提供する即時利用可能なオプションと比較して、いくつかの利点があります。
  • 可用性の高いCoherenceクラスタにセッション状態が格納されるため、Webサーバーの障害に対するセッションの回復力が高まります。

  • セッションがメモリーに格納されるため、SQL Serverセッション・プロバイダを使用してディスクに対してシリアライズする場合よりもアクセスが大幅に高速になります。

  • リレーショナル・データベースとは異なり、Coherenceクラスタは簡単にスケール・アウトして負荷の増加に対応できます。

  • 場合によっては、Coherenceのニア・キャッシュ機能を利用することにより、インプロセス速度でセッション・データにアクセスできます。

  • セッション状態は、複数のASP.NETアプリケーションで共有できます。

Coherence ASP.NETセッション管理の設定

ASP.NETセッションを管理するには、Coherenceのセッション・プロバイダを有効にしてASPセッション・キャッシュを構成する必要があります。

この項には次のトピックが含まれます:

ASP.NETセッション管理用のCoherenceクラスタの構成

クラスタ側サポートの場合は、クラスパスにcoherence-aspnet-session.jarを追加します。

これにより、セッション記憶域およびセッション属性のオーバーフローに使用される2つの分散キャッシュが構成され、ASP.NETアプリケーションが接続できる拡張プロキシが起動されます。プロキシ・サービスのアドレスとポートは、coherence.aspnet.extend.addressおよびcoherence.aspnet.extend.portシステム・プロパティを使用して構成できます。

ASP.NETアプリケーションの構成

Coherenceセッション・プロバイダでは、Extendクライアントのキャッシュ構成ファイルに、セッション記憶域キャッシュ用とセッション・オーバーフロー・キャッシュ用のリモート・キャッシュ・スキームを含める必要があります。他のリモート・キャッシュと同様に、サーバー上のキャッシュ名とクライアントの名前は同じである必要があります。即時利用可能な構成は、デフォルトのサーバー側構成とともに使用できます。

ソリューションにCoherence.dllを追加した後、セッション・ミドルウェアを有効にする必要があります。これを行うには、Program.csに次のものが含まれている必要があります:
  • Coherence ASP.NETセッションのサポートを構成するためのコール

  • アプリケーション・セッション状態に必要なサービスを追加するためのAddSessionのコール

  • アプリケーションのセッション状態を自動的に有効にするためのUseSessionのコール

Coherence ASP.NETセッションのサポートを構成するには、appsettings.jsonファイルのCoherenceSessionセクションで構成オプションを指定するか、UseCoherenceSessionコールで構成オプションを直接指定します。

appsettings.jsonの例

{
  "AllowedHosts": "*",
  "CoherenceSession": {
    "ApplicationId": "demo-app",
    "Model": "split",
    "MinOverflowAttributeSize": 10240
  }
}

Program.csの例

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

// configure Coherence session support based on Coherence configuration specified in appsettings.json:
builder.Services.UseCoherenceSession(builder.Configuration.GetSection(CoherenceSessionOptions.CONFIG));

// or configure Coherence session support directly in the code:
builder.Services.UseCoherenceSession(options =>
    {
        options.ApplicationId = "demo-app";
        options.Model = CoherenceSessionOptions.SessionModel.Split;
        options.MinOverflowAttributeSize = 10240;
    }
);
// uncomment when using .NET 8:
/*
builder.Services.AddDataProtection()
        .PersistKeysToFileSystem(new DirectoryInfo(@"/tmp"))
        .SetApplicationName("DemoApp");
*/
builder.Services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromSeconds(900);
	options.Cookie.Name = ".DemoApp.Session";
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    }
);

var app = builder.Build();

// Adds the SessionMiddleware automatically enable session state for the application
app.UseSession();

app.MapControllers();
app.Run();

構成オプション:

  • Model

    • Monolithic - すべてのセッション状態を単一のエンティティとして保存し、すべての属性を単一の操作としてシリアライズおよびデシリアライズします。

    • Split - 大きいセッション属性を独立した物理エンティティに分割し、属性ごとに1つのキャッシュ・エントリを作成し、それらを個別のキャッシュに格納します。

  • MinOverflowAttributeSize - 別々に格納される属性の最小サイズを定義します(Splitセッション・モデルにのみ適用されます)。

  • CoherenceConfig - Coherence構成ファイルへのパス(デフォルトでは、assembly://Coherence/Tangosol.Config/coherence-config.xmlに設定)。

  • CacheConfig - Coherenceキャッシュ構成ファイルへのパス(デフォルトでは、assembly://Coherence.SessionStore/Tangosol.Config/coherence-aspnet-cache-config.xmlに設定)。

  • ApplicationId - セッション・キーの一部として使用されるアプリケーションID。設定しない場合、IHostEnvironment.ApplicationName値がかわりに使用されます。

必要に応じて、デフォルトのCoherenceConfigおよびCacheConfigファイルをオーバーライドすることで、サーバー側の構成と同期する必要があるカスタム構成を指定できます。

セッション・モデルの選択

アプリケーションの要件に応じて異なるモデルを使用してセッション状態を格納するようにCoherenceのセッション・プロバイダを構成できます。

この項には次のトピックが含まれます:

セッション・モデルの概要

セッション・モデルは、クラスタ内のセッション状態をCoherenceセッション・プロバイダでどのように物理的に表現し、保存するかを記述します。プロバイダは、次の2つの異なる即時利用可能なセッション・モデル実装を備えています:

  • モノリシック・モデル - すべてのセッション状態を単一のエンティティとして保存し、すべての属性を単一の操作でシリアライズおよびデシリアライズします。

  • 分割モデル – モノリシック・モデルと同様に、小さいセッション属性を単一のエンティティに格納しますが、大きいセッション属性を独立した物理エンティティ(属性ごとに1つのエントリ)に分割し、個別のキャッシュに格納します。

モノリシック・モデルがデフォルトです。

セッション・モデルの指定

セッション・モデルを構成するには、Program.csまたはappsettings.jsonファイルのCoherenceSessionセクションでModel構成オプションを設定します。分割モデルを使用する場合、MinOverflowAttributeSizeオプションを最小サイズ(デフォルトでは1024に設定)に設定することで、別々に格納される属性の最小サイズを構成できます。

アプリケーション間でのASP.NETセッション状態の共有

複数のASP.NETアプリケーション間でセッションを共有すると有益な場合があります。デフォルトでは、セッション・キーは、アプリケーション識別子(IHostEnvironment.ApplicationNameプロパティによって返される)とセッション識別子を結合することによって特定されます。これにより、セッション共有を効果的に防止できます。

セッションを共有するには、アプリケーションのアプリケーションIDが同じである必要があります。特定のアプリケーション識別子を使用するようにCoherenceを構成するには、CoherenceSessionOptionsインスタンスのapplicationIdオプションを設定するか、appsettings.jsonCoherenceSession.ApplicationIdを指定します。

詳細構成

カスタム・セッション記憶域およびセッション・オーバーフロー・キャッシュを定義する場合、キャッシュ名はそれぞれaspnet-session-storageおよびaspnet-session-overflowである必要があります。また、記憶域キャッシュは、ConfigurablePofContextクラスをシリアライザとして使用するように構成する必要があります。

デフォルトのクラスタ・キャッシュ構成coherence-aspnet-config.xmlファイル

<cache-config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/coherence/coherence-cache-config"
              xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-cache-config coherence-cache-config.xsd"
              xml-override="{coherence.aspnet.cacheconfig.override}">

  <defaults>
    <scope-name system-property="coherence.aspnet.scope">AspNet</scope-name>
    <serializer>pof</serializer>
  </defaults>

  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>aspnet-session-storage</cache-name>
      <scheme-name>aspnet-session-storage</scheme-name>
      <interceptors>
        <interceptor>
          <name>session-cleanup-interceptor</name>
          <instance>
            <class-name>com.oracle.coherence.aspnet.session.internal.SessionCleanupInterceptor</class-name>
          </instance>
        </interceptor>
      </interceptors>
    </cache-mapping>

    <cache-mapping>
      <cache-name>aspnet-session-overflow</cache-name>
      <scheme-name>aspnet-session-overflow</scheme-name>
      <interceptors>
        <interceptor>
          <name>index-interceptor</name>
          <instance>
            <class-name>com.oracle.coherence.aspnet.session.internal.IndexInterceptor</class-name>
          </instance>
        </interceptor>
      </interceptors>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <distributed-scheme>
      <scheme-name>aspnet-session-storage</scheme-name>
      <service-name>Sessions</service-name>
      <backing-map-scheme>
        <local-scheme>
          <unit-calculator>BINARY</unit-calculator>
        </local-scheme>
      </backing-map-scheme>
      <autostart>true</autostart>
    </distributed-scheme>

    <distributed-scheme>
      <scheme-name>aspnet-session-overflow</scheme-name>
      <service-name>Sessions</service-name>
      <backing-map-scheme>
        <local-scheme>
          <unit-calculator>BINARY</unit-calculator>
        </local-scheme>
      </backing-map-scheme>
    </distributed-scheme>

    <proxy-scheme>
      <scheme-name>aspnet-proxy</scheme-name>
      <service-name>SessionProxy</service-name>
      <acceptor-config>
        <tcp-acceptor>
          <local-address>
            <address system-property="coherence.aspnet.extend.address"/>
            <port system-property="coherence.aspnet.extend.port"/>
          </local-address>
        </tcp-acceptor>
      </acceptor-config>
      <autostart>true</autostart>
    </proxy-scheme>
  </caching-schemes>
</cache-config>

デフォルトの.NETクライアント・キャッシュ構成coherence-aspnet-cache-config.xmlファイル

<cache-config xmlns="http://schemas.tangosol.com/cache">
  <caching-scheme-mapping>
    <cache-mapping>
      <cache-name>aspnet-session-storage</cache-name>
      <scheme-name>aspnet-session-remote</scheme-name>
    </cache-mapping>
    <cache-mapping>
      <cache-name>aspnet-session-overflow</cache-name>
      <scheme-name>aspnet-session-remote</scheme-name>
    </cache-mapping>
  </caching-scheme-mapping>

  <caching-schemes>
    <remote-cache-scheme>
      <scheme-name>aspnet-session-remote</scheme-name>
      <service-name>AspNet:SessionProxy</service-name>

      <initiator-config>
        <tcp-initiator>
          <name-service-addresses>
            <socket-address>
              <address system-property="coherence.ns.address">127.0.0.1</address>
              <port system-property="coherence.ns.port">7574</port>
            </socket-address>
          </name-service-addresses>
        </tcp-initiator>
        <serializer>
          <class-name>Tangosol.IO.Pof.ConfigurablePofContext, Coherence</class-name>
          <init-params>
            <init-param>
              <param-type>string</param-type>
              <param-value>assembly://Coherence.SessionStore/Tangosol.Config/coherence-aspnet-pof-config.xml</param-value>
            </init-param>
          </init-params>
        </serializer>
      </initiator-config>
    </remote-cache-scheme>
  </caching-schemes>
</cache-config>

イベント・インターセプタの登録

分割セッション・モデルを使用すると、セッションの属性は2つのキャッシュに格納されます。小さいHTTPセッション属性は1つのキャッシュ内で管理され、大きい属性は別のキャッシュに分割されます。これにより、小型の属性に頻繁にアクセスすることによってオーバーヘッドが生じることなく、非常に大型のHTTPセッション・オブジェクトをサポートできます。したがって、両方のキャッシュの同期を維持するには、イベント・リスナー(com.oracle.coherence.aspnet.session.internal.SessionCleanupInterceptor)が推奨されます。これにより、セッションがユーザーによって明示的に終了された場合およびエビクションまたは失効によって削除された場合、セッションの小さなセグメントと大きなセグメントの両方が、2つのキャッシュから一貫して削除されます。

キャッシュされたデータへのアクセスを高速化するために、オーバーフロー・キャッシュに索引を作成することをお薦めします。com.oracle.coherence.aspnet.session.internal.IndexInterceptorインターセプタは、オーバーフロー・キャッシュが作成された後に索引を作成します。

デフォルト構成は、両方のインターセプタで事前構成されています。