【Tomcat】Tomcatのセッション永続化 ~ セッション レプリケーション / MySQL編 ~

はじめに

 * セッションをDBに保存する
 * 用語、使用上の注意などは、以下の関連記事を参照のこと。
http://blogs.yahoo.co.jp/dk521123/33726907.html

手順概要

[1] JDBCドライバを【Tomcat Home】/lib配下に格納
[2] Sessionデ用のDB、テーブルを用意する
[3] Tomcatの設定を修正
 [3-1] context.xml
 [3-2] server.xml
 [3-3] catalina.properties
 [3-4] web.xml
[4] Tomcatを再起動する
[5] 動作確認

詳細手順

構築環境

 * OS     : CentOS7
 * DB     : MySQL
 * Java   : openjdk version 1.8.0_111
 * Tomcat : Apache Tomcat v8.5.11

前提条件

 * Tomcatをインストールしておくこと
  => 今回は、以下の関連記事でインストールした構成で行う
http://blogs.yahoo.co.jp/dk521123/36706185.html

[0] 準備 : JDBCドライバのダウンロード

 * JDBCドライバをダウンロード(今回は「mysql-connector-java-5.1.40.zip」)し、
   JARファイル(今回は「mysql-connector-java-5.1.40-bin.jar」)を取り出す
https://dev.mysql.com/downloads/connector/

[1] JDBCドライバの設定

[1] [0]のJDBCドライバを【Tomcat Home】/lib配下に格納する
~~~~
sudo cp ~/mysql-connector-java-5.1.40-bin.jar /usr/local/tomcat/lib/.
~~~~

[2] Session用 DB / テーブル作成

[2] Session用 DB / テーブルを作成する
~~~~
CREATE TABLE `tomcat_sessions` (
  `session_id`            VARCHAR(100)    NOT NULL COMMENT 'セッションID',
  `session_valid`         CHAR(1)         NOT NULL COMMENT 'スワップアウトした際に有効にするか',
  `session_max_inactive`  INT             NOT NULL COMMENT '最大無応答間隔',
  `session_last_accessed` BIGINT          NOT NULL COMMENT '最終アクセス時間',
  `session_app`           VARCHAR(255)    DEFAULT NULL COMMENT 'アプリケーション名',
  `session_data`          MEDIUMBLOB COMMENT 'セッションデータ',
  PRIMARY KEY (`session_id`),
  KEY kapp_name (`session_app`)
)
COMMENT='セッション'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
~~~~

[3] Tomcatの設定を修正

[3-1] context.xml を修正する
以下を参考に。
https://tomcat.apache.org/tomcat-8.5-doc/config/manager.html#Nested_Components
sudo cp /usr/local/tomcat/conf/context.xml /usr/local/tomcat/conf/context.xml.backup

sudo vi /usr/local/tomcat/conf/context.xml
~~~~
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->

<!-- ★追加(実際にはコメント文は省いてください)★ -->
<Manager className="org.apache.catalina.session.PersistentManager"
      saveOnRestart="true"
      maxIdleBackup="0"
      maxIdleSwap="0"
      minIdleSwap="10"
      processExpiresFrequency="1"
      maxActiveSessions="-1"
     >  
     <Store className="org.apache.catalina.session.JDBCStore"  
         connectionURL="jdbc:mysql://localhost:3306/tomcat_db?useSSL=false&amp;characterEncoding=UTF-8"  
         connectionName="root"                          <!-- 【DBユーザ名】 -->
         connectionPassword="password"                  <!-- 【DBパスワード】 -->
         driverName="com.mysql.jdbc.Driver"
         sessionTable="tomcat_sessions"                 <!-- テーブル名 -->
         sessionIdCol="session_id"                      <!-- テーブル・項目名 -->
         sessionValidCol="valid_session"                <!-- テーブル・項目名 -->
         sessionMaxInactiveCol="session_max_inactive"   <!-- テーブル・項目名 -->
         sessionLastAccessedCol="session_last_accessed" <!-- テーブル・項目名 -->
         sessionAppCol="session_app"                    <!-- テーブル・項目名 -->
         sessionDataCol="session_data"                  <!-- テーブル・項目名 -->
      />
</Manager>
<!-- ★追加★ -->
</Context>
~~~~


`設定値`意味`デフォルト値`備考
saveOnRestarttomcat停止時にセッションを保存するかtrue
maxIdleBackupセッションが最後に使われてからバックアップされるまでの時間 [秒]-1(非活性)
minIdleSwapセッション数が maxActiveSessions を越えたとき、スワップアウト(DBへの保管)が発生するが、ここで指定した秒数を超えない限りはスワップアウトされない-1(非活性)
processExpiresFrequencyセッション切れ頻度6最小値1
maxActiveSessionsメモリ内に保持するセッション数-1(未制限)

[3-2] server.xml を修正する

sudo cp /usr/local/tomcat/conf/server.xml /usr/local/tomcat/conf/server.xml.backup

sudo vi /usr/local/tomcat/conf/server.xml
~~~~
【修正前】
<Engine name="Catalina" defaultHost="localhost">

【修正後】
<Engine name="Catalina" defaultHost="localhost"
 jvmRoute="jvm1" backgroundProcessorDelay="1" startStopThreads="-1">
~~~~

`設定値`意味`デフォルト値`備考
jvmRouteロード・バランシング時にセッションを識別するための値null
backgroundProcessorDelaybackgroundProcessメソッド呼び出しの遅延時間を設定10秒
startStopThreadsスレッド数10 : Runtime.getRuntime().availableProcessors()、負の数:Runtime.getRuntime().availableProcessors() + value

[3-3] catalina.properties を修正する

sudo cp /usr/local/tomcat/conf/catalina.properties /usr/local/tomcat/conf/catalina.properties.backup

sudo vi /usr/local/tomcat/conf/catalina.properties
~~~~
#tomcat.util.buf.StringCache.cacheSize=5000

#★追加★
org.apache.catalina.session.StandardSession.ACTIVITY_CHECK=true"
~~~~

[3-4] 【Tomcat】/webapps/【自分プロジェクト】/WEB-INF/web.xml を修正する

「<distributable />」を追記

sudo cp /usr/local/tomcat/webapps/examples/WEB-INF/web.xml /usr/local/tomcat/webapps/examples/WEB-INF/web.xml.backup

sudo vi /usr/local/tomcat/webapps/examples/WEB-INF/web.xml
~~~~
  ・・・略・・・
  <distributable />
</web-app>
~~~~

[4] Tomcatを再起動する

systemctl restart tomcat

[5] 動作確認

[1] 以下の関連記事の「【動作確認用サイト】sessionExam.jsp」を
   「/usr/local/tomcat/webapps/examples」配下に置く
http://blogs.yahoo.co.jp/dk521123/36708242.html
[2] ブラウザのURL欄に以下のURLを入れる
[[http://localhost/examples/sessionExam.jsp]]
[3] DB内のテーブル「tomcat_sessions」をみてみる
 => データが確認できることを確認する

トラブルシューティング

はまりポイント

 1) JDBCドライバを設定(手順[1])し忘れる
 2) 「[3-1] context.xml を修正する」でconnectionURLの&の部分をエスケープ「&amp;」する
 3) アプリケーションの web.xml に distributable の指定(手順[3-4])を忘れる

困ったら...

[1] Apache / Tomcat / MySQL のログを確認する
 * Apacheログ(デフォルトだと「/var/log/httpd/error_log」「/var/log/httpd/access_log」)
 * Tomcatログ(デフォルトだと「【Tomcat Home】/logs/httpd/manager.YYYY-MM-DD.log」など)
 * MySQLログ(デフォルトだと「/var/log/mysqld.log」)

# Tomcatログ「manager.YYYY-MM-DD.log」をみて、JDBCドライバの入れ忘れに気づけた


関連記事

Tomcatのセッション永続化 ~ セッション レプリケーション / DynamoDB編 ~

http://blogs.yahoo.co.jp/dk521123/36725545.html

Amazon DynamoDB について

http://blogs.yahoo.co.jp/dk521123/36716365.html

Tomcatのセッション永続化 ~ セッション レプリケーション / 知識編 ~

http://blogs.yahoo.co.jp/dk521123/33726907.html

Tomcatのセッション永続化 ~ セッション レプリケーション / JDBCManager・MySQL編 ~

http://blogs.yahoo.co.jp/dk521123/36698011.html

Linux】【TomcatTomcat 8.5 のインストール

http://blogs.yahoo.co.jp/dk521123/36706185.html

Linux】【Tomcat】 単一Tomcat で複数のインスタンスを動かす

http://blogs.yahoo.co.jp/dk521123/36706243.html

Apache】【TomcatApache - Tomcat で、ロードバランシング

http://blogs.yahoo.co.jp/dk521123/36708242.html