セッションレプリケーション機能とは
セッションレプリケーション機能は、Webコンテナのプロセスダウンまたはマシンダウン、パブリッククラウドの仮想マシンのスケールインが発生した場合に、他の運用中のWebコンテナでServletのセッション情報を引き継ぎ、Webアプリケーションの運用を継続して可能にする機能です。
セッション情報は、Webコンテナ内で、Webアプリケーション単位に管理されています。通常、Webコンテナがダウンした場合、そのコンテナ内に格納されたセッション情報は破棄されてしまいます。
セッションレプリケーション機能を有効にすると、Webコンテナで生成されたセッション情報が、セッションストアにバックアップされます。異常やスケールインの発生時には、他のWebコンテナにセッション情報をリカバリーして引き継ぎ、継続して処理を行うことができます。
また、GlassFish Serverクラスターを再起動した場合に、再起動前のServletのセッションを破棄せずに継続して使用することも可能になります。
注意
セッションレプリケーション機能は、GlassFish Serverクラスターで利用できます。DASでは利用できません。
また、異なるバージョンのGlassFish間では利用できません。
セッションのバックアップ
スケールイン発生時のセッションのリカバリー
障害発生時のセッションのリカバリー
セッションレプリケーション機能の構成要素
セッションレプリケーション機能は、以下によって構成されています。
セッションストアは、GlassFish Serverクラスターで使用しているServletのセッション情報をバックアップするデータストアです。
障害やスケールインの発生時は、セッションストアからセッションをリカバリーすることで、障害やスケールインの発生前のセッション情報を使用し、Webアプリケーションを継続して運用することができます。
セッションストアには、Redisを使用します。
Webアプリケーションの実行環境です。
障害やスケールインの発生時にWebアプリケーションを継続して運用するためには多重プロセス、または、複数マシンで環境を構築する必要があります。
注意
DASでセッションレプリケーションを利用することはできません。
また、異なるバージョンのGlassFish間でセッションレプリケーションを利用することはできません。
複数マシンで環境を構築する場合、GlassFish Serverクラスターを運用する各マシンには、異なるホスト名をもつマシンを使用してください。
セッションレプリケーションマネージャーは、セッションレプリケーション機能有効時、GlassFish Serverインスタンス(Webコンテナ)にアドインして標準のセッション管理モジュールにかわって動作し、セッションの管理とセッションストアとの通信を行います。
リクエスト処理を安定化するための仕組みとしてセッション情報のローカルキャッシュをもち、セッションストアへのバックアップ後もセッション情報をWebコンテナ上に維持します。
ロードバランサー(HTTP/HTTPSトラフィックを受け付けるレイヤー7ロードバランサー)は、Webブラウザー(HTTPクライアント)から受けたリクエストをWebコンテナに転送する役割を持っています。
通常、ロードバランサーはWebブラウザーからのリクエストを受け付けて、ロードバランサーに設定された方法でWebコンテナへリクエストを振り分けます。
何らかの原因で一部のWebコンテナにリクエストを振り分けることができなくなった場合は、他の運用可能なWebコンテナにリクエストを振り分けることでWebアプリケーションの継続運用を実現します。
ロードバランサーとして、リバースプロキシ用に構成したWebサーバーや、クラウド環境のレイヤー7ロードバランサーを使用できます。
ロードバランサーでは、スティッキーセッション機能(リクエストに付加されているセッションの識別情報をもとに、同じセッションのリクエストを同じWebコンテナへ振り分ける機能)を有効にする必要があります。
セッションはセッションストアにバックアップされます。
Webコンテナの異常やスケールインの発生時にセッションストアには、バックアップされたセッションを他のWebコンテナにリカバリーすることで、他のWebコンテナでセッションを引き継ぎます。
セッションのバックアップの契機
セッションをバックアップする契機は、以下の2種類から選択できます。
リクエストの完了後にセッションをバックアップします。
また、Webブラウザーへのレスポンスはセッションがセッションストアにバックアップされるのを待ってから完了します。
Webブラウザーからのリクエストの処理時間にセッションのバックアップ時間も含まれるため、Webブラウザーからのリクエストを処理する時間は一定間隔でバックアップする場合と比較して長くなります。
セッションはリクエスト処理が完了した後に、Webコンテナによって定期的にバックアップされます。
リクエスト処理とは独立してバックアップが行われるため、リクエストごと(完了後)にバックアップする場合と比べて、リクエストの処理時間への影響を抑えることができます。
セッションがセッションストアにバックアップされる前にWebコンテナがダウンした場合、そのセッションはリカバリーすることができません。
設定方法
バックアップの契機は、セッションレプリケーションマネージャーのライフサイクルモジュールのプロパティ(backupMode)で設定します。デフォルト値は、「一定間隔でバックアップする」で、バックアップする間隔のデフォルト値は、5秒です。
バックアップの各契機について、以下の関係が成り立ちます。
|
注意
一定間隔でバックアップする設定でも、セッションのリカバリーが発生したリクエストでは、セッションのロック解除のため、そのリクエストの処理の完了時にセッションがバックアップされます。セッションのロックの詳細については、「4.11.1.4 Webコンテナ間のセッションのロック」を参照してください。
アプリケーション内でレスポンスの出力ストリームをクローズした場合は、その時点でWebブラウザーにレスポンスが送信されます。この場合、リクエストごと(完了後)にバックアップする設定であっても、セッションがバックアップされるのはアプリケーションの業務処理が終了してからとなるため、Webブラウザーへのレスポンスの送信がセッションのバックアップよりも先になります。そのため、レスポンス送信後にWebコンテナがダウンした場合であっても、Webコンテナがダウンしたタイミングがバックアップ前だった場合には、そのレスポンスで使用していた最新のセッション情報をリカバリーすることはできません。
参照
セッションレプリケーションマネージャーの設定については、「5.17.4 セッションレプリケーションマネージャーの設定」を参照してください。
セッションのバックアップに失敗した場合
セッションのバックアップに失敗した場合でも、Webブラウザー、および、Webアプリケーションへエラーの通知は行われません。これは、セッションのバックアップに失敗した場合、Webブラウザー、および、Webアプリケーションにエラーを通知するとセッションレプリケーション機能を使用することがアプリケーションの稼働率を下げる要因となってしまうためです。
また、セッションのバックアップに失敗した場合は、失敗を示すメッセージがサーバーログに出力された後、失敗したGlassFish Serverインスタンスでは以降セッションストアは使用不可とマークされ、使用可能となるまで通信(バックアップ、リカバリー)を行いません。
参照
セッションストアが使用可能になる契機については、「4.11.1.5 セッションレプリケーション機能の監視」を参照してください。
バックアップ元のセッション情報の破棄
セッションが他のWebコンテナにリカバリーされた場合、バックアップ元のWebコンテナのローカルキャッシュに古いセッション情報が残る場合があります。このような古いセッション情報は、セッションレプリケーションマネージャーによって定期的に破棄されます。
参照
セッションレプリケーションマネージャーがローカルキャッシュの古いセッション情報を破棄する契機については、「ローカルキャッシュの定期削除」を参照してください。
セッションのリカバリー処理
Webコンテナは、Webブラウザーから通知されてきたセッションIDに該当するセッションを保持していない場合(もともとそのセッションを扱っていたWebコンテナがダウンした場合や、ロードバランサー上のスティッキーセッションの維持期間が切れた場合など)、次の図のように他のコンテナによりバックアップされているセッションをセッションストアから取得し、リクエストを処理します。
ロードバランサーは、WebコンテナAにリクエストを送ろうとしましたが、WebコンテナAの障害やスケールインの発生により、リクエストの送信に失敗しました。
または、もともとWebコンテナAにリクエストが振り分けられていたセッションについて、ロードバランサー上のスティッキーセッションの維持期間が切れました。
ロードバランサーは、WebコンテナBにリクエストを振り分けます。
WebコンテナBは、送られてきたセッションが自分の所有するセッションではないため、バックアップされたセッションをセッションストアから取得してリカバリーします。
セッションストアの障害などによりWebコンテナBがセッションをセッションストアから取得できなかった場合、セッションはWebコンテナBにリカバリーされません。
このとき、getSession()、getSession(true)の場合は新規セッション、getSession(false)の場合はnullがアプリケーションに返却されます。
HttpSessionActivationListener
セッションに結びつけられているオブジェクトは、セッションの非活性化や活性化といったコンテナのイベントからの通知を受けることができます。
Java VM間でセッションを移動させたりセッションを持続させたりするコンテナは、セッションに結びつけられている属性のうちHttpSessionActivationListener を実装しているすべての属性に通知することを要求されます。
イベント | メソッド | |
---|---|---|
sessionWillPassivate | sessionDidActivate | |
リカバリー時 | 元のWebコンテナで実行(注) | リカバリー先のWebコンテナで実行 |
Webコンテナ停止時 | セッションをバックアップする前に実行 | - |
注) リカバリー後、ローカルキャッシュの定期削除が実行されるタイミングでイベントが通知されます。
参照
Webコンテナ停止時のセッションのバックアップについては、「Webコンテナ正常終了時のセッションのリカバリー範囲」を参照してください。
セッションをリカバリーできない場合
セッションレプリケーション機能を使用していても、以下の場合、セッションのリカバリーはできません。
セッションがバックアップされる前にWebコンテナがダウンした。
セッションストアの障害やエビクションポリシー(容量制限到達時のデータの削除)などによりセッションストアのセッション情報が削除され、そのセッションについてのリカバリーが発生した。
セッションストアの障害などによりセッションストアとの通信に失敗した。
セッションがすでに他のWebコンテナによってロックされていて、「セッションロックの取得待ち時間」を経過してもロックを取得できなかった。
その他の予期しない異常が発生した。
参照
セッションのリカバリーされる範囲については、「4.11.2 セッションレプリケーション機能のリカバリー範囲」も参照してください。
Webコンテナはセッション情報のローカルキャッシュをもち、セッション情報をセッションストアにバックアップした後も、セッション情報をWebコンテナ上に維持します。これにより、次のリクエスト時にそのセッション情報を使用して処理を行うことが可能となるため、リクエストごとのセッションのリカバリーが発生せず、性能影響を抑えることが可能となります。
Webコンテナが処理するセッション情報の量に応じて、Javaヒープサイズをチューニングする必要があります。
参照
Javaヒープサイズのチューニングについては、「7.5.2 Javaヒープのチューニング」を参照してください。
ローカルキャッシュの定期削除
Webコンテナ上のセッションのローカルキャッシュは、セッションレプリケーションマネージャーによって定期的に削除されます。定期削除処理では、次のようなセッションのローカルキャッシュが削除されます。
期限切れ(タイムアウト)になったセッション
他のWebコンテナでリカバリーが実行されたセッション
定期削除処理の実行間隔は、glassfish-web.xmlのreapIntervalSecondsプロパティで設定します。デフォルトは60秒です。
参照
設定の詳細については、「5.17.4 セッションレプリケーションマネージャーの設定」を参照してください。
ローカルキャッシュとセッションストアの同期
次のような場合に、Webコンテナのローカルキャッシュとセッションストア上のセッション情報との同期をとる処理が実行されます。
Webコンテナを起動するとき、停止するとき
Webコンテナとセッションストアの通信が回復したとき
ローカルキャッシュのセッション情報が他のWebコンテナによってリカバリーされておらず、ローカルキャッシュのセッション情報がセッションストアよりも新しい(またはセッションストアに存在しない)場合、ローカルキャッシュのセッション情報がセッションストアにバックアップされます。
ローカルキャッシュのセッション情報が他のWebコンテナによってリカバリーされている場合、ローカルキャッシュのセッション情報が削除されます。
ロードバランサーのスティッキーセッション機能による同一Webコンテナへのリクエストの振り分けが出来なくなった場合(もともとそのセッションを扱っていたWebコンテナが停止した場合や、ロードバランサー上のスティッキーセッションの維持期間が切れた場合など)、同時に発生した同一セッションのリクエストが複数の異なるWebコンテナに割り振られる可能性があります。このようなとき、複数のWebコンテナで同じセッションのリカバリーが実行されることになるため、複数のWebコンテナでセッション情報を扱う際のデータの整合性に注意する必要があります。
セッションレプリケーション機能では、Webコンテナでセッションをリカバリーする際にそのセッションに対するロックを取得し、他のWebコンテナで同時に同じセッションのリカバリーが実行されていないことを確認してからセッションをリカバリーします。つまり、あるWebコンテナでセッションのリカバリーが実行されている間、同じセッションをリカバリーしようとするWebコンテナは、そのセッションがバックアップされるまで待機します。このセッションがバックアップされるまで他の処理を待機させる制御を、セッションのロックと呼びます。これにより、可能な限りセッション情報の整合性を保とうとします。
Webコンテナでリカバリーしたセッションのリクエスト処理が完了したとき、セッションがセッションストアにバックアップされ、セッションのロックが解除されます。セッションのリカバリーが発生したリクエストでは、セッションのロック解除のため、そのリクエストの処理の完了時にセッションがバックアップされます。
WebコンテナAの故障やスケールインなどにより、ロードバランサーのスティッキーセッション機能による同一Webコンテナへのリクエストの振り分けが出来なくなります。
ロードバランサーがWebコンテナBにリクエストを振り分けます。
同時期に、同じセッションの別のリクエストをロードバランサーがWebコンテナCに振り分けます。
WebコンテナBはセッションストアにセッション情報を問い合わせます。このとき、そのセッションが他のWebコンテナでリカバリーされていないことを確認し、セッションをロックします。
WebコンテナBはセッションをリカバリーします。
WebコンテナCがセッションストアにセッション情報を問い合わせます。このとき、そのセッションがWebコンテナBでリカバリーされているため、そのセッションがWebコンテナBからバックアップされるまで待機します。
WebコンテナBはセッションストアにセッションをバックアップし、ロックを解除します。
WebコンテナCは、WebコンテナBによってバックアップされたセッションをロックして、リカバリーします。
WebコンテナCはセッションストアにセッションをバックアップし、ロックを解除します。
ロックのタイムアウト
ロックの取得待ち時間を過ぎても他のWebコンテナのセッションがバックアップされない場合、セッションはリカバリーされません。このとき、getSession()、getSession(true)の場合は新規セッション、getSession(false)の場合はnullがアプリケーションに返却されます。ロックの取得待ち時間は、セッションレプリケーションマネージャーのライフサイクルモジュールのプロパティ(sessionLockWaitTime)で設定します。
セッションのロックを取得したWebコンテナが異常終了するなどでロックが永久に解除されなくなることを防ぐために、セッションのロックには存続期間が設定されます。セッションのロックの存続期間は、セッションレプリケーションマネージャーのライフサイクルモジュールのプロパティ(sessionLockTTL)で設定します。
参照
セッションレプリケーションマネージャーの設定については、「5.17.4 セッションレプリケーションマネージャーの設定」を参照してください。
注意
同時期に複数のWebコンテナで同じセッションのリカバリーが実行された場合、各Webコンテナが同じセッションのローカルキャッシュをもつ状態になります。そのため、ローカルキャッシュをもつWebコンテナで古いローカルキャッシュの削除が実行される前に再びセッション情報が使用された場合、別のWebコンテナで更新されたセッション情報ではなく、ローカルキャッシュの古いセッション情報が使用されてしまう可能性があります。
この状況の発生率を下げるためには、ローカルキャッシュの定期削除の間隔を短くしてください。
ローカルキャッシュの定期削除については「ローカルキャッシュの定期削除」を参照してください。
Webコンテナ間のセッションのロックは、複数のWebコンテナにおけるリカバリーの同時実行を抑制し、リカバリーが順番に実行されるようにします。この仕組みにより、最新のセッション情報を保有するWebコンテナが一意に決まるため、そのWebコンテナからのみセッションストアにセッションをバックアップできるようになります。一方で、Webコンテナ間のセッションのロックは、ローカルキャッシュのセッション情報の使用を制御する仕組みではないため、別のWebコンテナでセッションが更新されたことでローカルキャッシュが古くなった場合に、古いセッション情報が使用されることを防ぐことはできません。また、古いセッション情報はセッションストアにバックアップされません。
この状況の発生率を下げるためには、ローカルキャッシュの定期削除の間隔を短くしてください。
セッションのロックの存続期間を超過してもロックが解除されなかった場合や、セッションストアのダウンによりセッションのロックに関する管理情報が消失した場合には、セッションのロックが解除され、他のWebコンテナがセッションをリカバリーできるようになります。
セッションのロックの存続期間を超過することによる意図しないロックの解除を防ぐには、アプリケーションの処理時間に合わせてセッションのロックの存続期間(sessionLockTTL)をチューニングしてください。チューニング方法については、「7.5.1 各タイムアウト値の設定について」を参照してください。
セッションのリカバリーが発生したリクエストでは、そのリクエストの処理の完了時にセッションがバックアップされます。このときのバックアップは、データの整合性を保つため、セッションのロックが解除された状態では実行されません。
意図しないロックの解除を防ぐには、アプリケーションの処理時間に合わせてセッションのロックの存続期間(sessionLockTTL)をチューニングしてください。
セッションレプリケーション機能を使用する場合、Webコンテナ(セッションレプリケーションマネージャー)は、セッションストアが使用可能かどうかを監視します。
セッションレプリケーションマネージャーは、セッションストアに一定間隔(10秒)で監視用のメッセージを送付し、正常にレスポンスが返ることを確認します。
応答待ち時間(20秒)内にレスポンスが返らない場合、セッションストアは使用不可にマークされセッションのバックアップ対象からはずされます。その後、使用不可にマークしたセッションストアから正常にレスポンスが返るようになった場合、そのセッションストアは使用可能とし、セッションのバックアップが行われます。
通常、セッションストア上のセッション情報は、セッションが無効になったとき、そのセッションを使用しているWebコンテナのセッションレプリケーションマネージャーによって破棄されます。
しかし、Webコンテナがダウンしている場合は、Webコンテナのセッションレプリケーションマネージャーによってセッションが破棄されないため、不要なセッションがセッションストア上に残り、セッションストアのリソースを圧迫します。
このようなリソースの圧迫を防ぐために、セッションレプリケーションマネージャーは、セッションストアに格納するセッション情報に存続期間を設定し、期限切れ(タイムアウト)となっているセッションが破棄されるようにします。
セッションストアに格納されるセッション情報は、存続期間を超えたキーを削除するセッションストアの機能によって、セッションの期限切れの後に削除されます。
セッションストアに格納された期限切れのセッションの存続期間(期限切れとなってからセッションが削除されるまでの期間)は、ライフサイクルモジュールのプロパティ(invalidSessionTTL)で設定します。
セッションストアに格納されたセッションは、期限切れとなった後、この存続期間が経過してから削除されます。
セッションストアからセッション情報が削除されるとき、Webコンテナがダウンしてセッションストアにのみセッションが存在する場合には、以下のセッション破棄関連処理が実行されません。
jakarta.servlet.http.HttpSessionListener#sessionDestroyed(jakarta.servlet.http.HttpSessionEvent)
jakarta.servlet.http.HttpSessionAttributeListener#attributeRemoved(jakarta.servlet.http.HttpSessionBindingEvent)
jakarta.servlet.http.HttpSessionBindingListener#valueUnbound(jakarta.servlet.http.HttpSessionBindingEvent)
セッションストアには、セッションレプリケーション用の管理情報がセッションごとに保存されます。この管理情報は、ローカルキャッシュの定期破棄処理でセッションのリカバリー状況を確認するために参照されることから、セッションが期限切れとなった後も一定期間セッションストアから削除されずに維持されます。この維持期間は、セッションレプリケーションマネージャーのライフサイクルモジュールのプロパティ(invalidSessionTTL)で設定される値です。
注意
ライフサイクルモジュールのプロパティinvalidSessionTTLは、次に示す指針に沿って設定してください。指針と異なる小さな値を設定した場合、ローカルキャッシュの定期削除処理が実行される前にセッションストアのセッションの管理情報が削除され、そのセッションに関するローカルキャッシュの定期削除処理が実行されなくなります。また、そのセッションに関するHttpSessionActivationListenerのイベント通知処理も実行されなくなります。
ローカルキャッシュの期限切れセッションの監視間隔(reapIntervalSeconds)よりも大きな値を設定してください。
Webコンテナとセッションストアの間の通信に関わる障害が発生した場合に、障害発生から復旧するまでにかかると想定される期間よりも大きな値を設定してください。
ライフサイクルモジュールのプロパティinvalidSessionTTLは、Webコンテナがローカルキャッシュの期限切れセッションを検出した時刻からの時間として適用されます。そのため、実際のセッションストア上のセッション情報の存続期間は、ローカルキャッシュの期限切れセッションの監視間隔(reapIntervalSeconds)程度の誤差が生じます。
参照
セッションレプリケーションマネージャーの設定については、「5.17.4 セッションレプリケーションマネージャーの設定」を参照してください。
セッションレプリケーション機能では、Webコンテナ(セッションレプリケーションマネージャー)とセッションストアの間で、データの通信が行われます。この通信は、SSL/TLSによる暗号化でセキュリティ保護されます。
また、パブリッククラウドのRedisサービスで提供されるRedis AUTHやRedis ACLに相当する機能を利用して、ユーザー認証を行うことができます。
参照
設定の詳細については、「5.17.3 セッションストアの設定」や「5.17.4 セッションレプリケーションマネージャーの設定」を参照してください。
セッションレプリケーションの対象は、シリアライズ(直列化)可能なオブジェクトであり、java.io.Serializableを実装する必要があります。セッションレプリケーション機能を利用した場合、シリアライズ不可なオブジェクトをセッション属性に格納(setAttribute)しようとすると、java.lang.IllegalArgumentExceptionが発生します。
また、セッション属性に格納するオブジェクトが保持するインスタンスフィールドについて、transient修飾子を付与して宣言することで、シリアライズの対象外となります。シリアライズ不可なフィールドを持たせることや、特定のフィールドをセッションレプリケーションの対象から外すことができます。
参照
詳細については、「5.17.1 セッションレプリケーション機能を利用する場合のWebアプリケーション作成方法」を参照してください。
セッションレプリケーション機能が出力するログは、以下の2箇所に出力されます。
システムログ/イベントログには出力されません。
GlassFish Serverクラスターのサーバーログ
GlassFish Serverクラスターのサーバーログに、セッションレプリケーションマネージャーのエラーメッセージ、警告メッセージ、情報が出力されます。
ログの出力先、ログファイルのロールオーバ、ログを保管する世代数は、GlassFish Server管理コンソールもしくはasadminコマンドで設定します。
セッションレプリケーショントレースログ
セッションレプリケーショントレースログに、セッションストアとの通信内容やセッションレプリケーション機能のイベントが出力されます。
詳細については、「5.10.6 セッションレプリケーショントレースログ」を参照してください。
パブリッククラウドのRedisサービスは、ログやメトリクスを採取するパブリッククラウド機能を通じて監視することができます。
詳細については、「5.17.3 セッションストアの設定」を参照してください。