ITエンジニアの成長ブログ

ITエンジニアとして行う勉強の発信&日々の生活で体験した楽しいことをゆるく発信

Tomcatのセッション情報の永続化について

今回は、Tomcatのセッション情報の永続化について確認したいと思います。

Tomcatのセッション情報の永続化とは?

まずは、そもそもの言葉の意味から説明します。

以前、Tomcatで稼働しているWebアプリケーションを動作確認していた時に、必要に応じてTomcatの再起動をしたのですが再起動前後でセッションの数が変わりませんでした。セッション情報はメモリにある情報なので、再起動したらリセットされる想定でした。

ちなみに、セッションの数はTomcat付属のmanagerアプリケーションで確認しました。以下の画面キャプチャの赤枠の部分ですね。

Tomcat Webアプリケーションマネージャ1

私が勝手に勘違いをしていたのですが、実はTomcatはデフォルトではTomcat停止時にセッション情報の永続化をしており、次回のTomcat開始時にその永続化したセッション情報を再読み込みすることで、再起動前のセッション情報を保持しておくことができます。

永続化という言葉は分かりづらいかもしれませんが、要するにメモリ上にあるセッションの値を一時的にファイルに吐き出しておくことを表しています。そうすることで、再起動前のセッション情報はそのファイルから復元することができます。

Tomcatのセッション情報の永続化の動作を簡単に確認してみる

自分の手元で簡単なアプリケーションを作成し、セッション情報の永続化の挙動を確認したいと思います。

以下の簡単なサーブレットで動作確認してみます。

@WebServlet("/CounterServlet")
public class CounterServlet extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    HttpSession session = request.getSession();
    Integer count = (Integer) session.getAttribute("count");
    
    if (count == null) {
      count = new Integer(0);
    }
    count = new Integer(count.intValue() + 1);
    session.setAttribute("count", count);

    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    out.println("<html><body>");

    out.println("<p>sessionId = " + session.getId());
    out.print("<p>count = " + count);
    
    String linkUrl = request.getRequestURI();
    out.println("<p><a href=\"" + linkUrl + "\">RELOAD</a>");
    out.println("</body></html>");
  }
}


上記のコードは、「/CounterServlet」でアクセス可能なサーブレットで、画面にセッションIDとカウンタ値を表示します。カウンタ値は、アクセスした回数を保持する値として、セッション値にアクセス回数を保持しておいてアクセスする毎に数値を+1ずつします。

それでは、アクセスしてみます(見ての通りコンテキスト名は「/sample」です)。アクセスすると、初回なのでカウンタ値は「1」です。それとセッションIDが表示されています。

初回アクセス

画面の「RELOAD」ボタンを押して再度アクセスすると、以下の通りカウンタ値が+1されて「2」になりました。セッションIDは変わりません。

2回目のアクセス

その後、複数回アクセスを行い、現在のカウンタ値は以下の通り「7」です。

7回目のアクセス

それでは、ここでTomcatを停止します。

10-Jun-2024 11:19:28.323 INFO [Thread-6] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]

そしたら、再度Tomcatを開始してもう一度「/CounterServlet」でサーブレットにアクセスしましょう。

8回目のアクセス

すると、上記の通りTomcat停止前の最後にアクセスした回数である「7」を+1した「8」がカウンタ値として表示されました。

このように、Tomcatを停止したとしてもその際にセッション値を保存しておいて、次回アクセス時に有効であればそのセッション情報を復元してくれます。これが、Tomcatのセッション情報の永続化です。

Tomcatのセッション情報の永続化の設定

さて、上記まででTomcatのセッション情報が永続化されていることを確認しましたが、実はこれは設定でON/OFFできます。

tomcat 8.5であれば、ドキュメントの以下に設定内容が記述されています。
Apache Tomcat 8 Configuration Reference (8.5.100) - The Manager Component

デフォルトでは、このセッション永続化はONになっています。これをOFFにしたい場合は、Webアプリケーション配下にMETA-INF/context.xmlを作成して、<Manager pathname="" />を追加します。以下のように記述します。

<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Manager pathname="" />
</Context>


上記の設定をしておくと、セッション情報は永続化されません。

そして、セッション情報の永続化がONになっている場合は、その永続化したセッション情報は"SESSIONS.ser"という名前のファイルにシリアライズされてディスクに保存されます。出力先は、Webアプリケーションのworkディレクトリ「${TOMCAT_HOME}/work/Catalina/localhost/<Webアプリケーションコンテキスト名>」です。

SESSIONS.ser

上記ファイルは、Tomcat停止時に作成され起動時には削除されました。

因みに、セッション情報へ登録するオブジェクトはおなじみの「java.io.Serializable」を実装しておく必要があります。実装しておかないと、セッション情報は復元されません。

おわりに

いかがでしょうか。セッション情報が永続化されることで、Tomcatが再起動したとしてもユーザーは以前の処理を継続して作業することができます。この挙動を理解しておかないと、セッション周りの障害が発生した場合に混乱してしまうので、しっかりと押さえておきたいところです。私は、この挙動を知らなかったので上司に誤った説明をしてしまったことがあります。。

今回はこの辺で。最後までお読みいただきありがとうございました。