概要
SpringSessionをそのまま使用すると、デフォルトであるとサービスのメモリ内でセッション情報を管理しているため、複数サーバでロードバランスしている場合などセッション情報が複数台サーバにある場合、使い勝手が悪いという弱点があります。
上記弱点を補うため、セッション情報を外部で管理する方法があり、管理方法はいくつかありますが、今回はDB(Postgresq1)に保存する方法を例に紹介しようとおもいます。
SpringSession 設定
SpringSessionがあらかじめ反映されている状態からDB設定を実施する手順を示します。
依存関係の追加
SpringSessionでDB格納する依存関係を追加する
dependencies {
implementation 'org.springframework.session:spring-session-jdbc'
}
SpringSession保存方式を指定
SpringSessionでSession情報をDB保存するよう「spring.session.store-type」に「jdbc」を指定
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=testDB
spring.datasource.password=xxxx
spring.session.store-type=jdbc
DDL設定
Session情報を格納するDDLをDBに反映する
CREATE TABLE public.SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BYTEA NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
Java実装
Controllerクラスで、HttpSessionに対しSession情報を設定
public class TestApiController {
@GetMapping
public String getTest(HttpSession session) {
session.setAttribute("sample", "sample");
return "retValue";
}
DB格納状態の確認
上記を実行しSession情報が格納されているかについて確認する
「SPRING_SESSION」テーブルを確認
Session登録時刻、最終更新時刻、Sessionタイムアウトまでの時刻、タイムアウトまでの時間が設定される
「SPRING_SESSION_ATTRIBUTES」テーブルを確認
HttpSettionで設定されたキーと値が設定される、値はバイナリ値で格納される
ブラウザ側のSession情報を確認
ブラウザ側にも同一セッション情報で渡ってきていることを確認
SessionIDはBase64エンコードされているため、デコードし確認する
「c8a2ba96-75c1-4ac1-9bf7-268d821ca05e」となり、DBに保存されているセッションコードと一致していることを確認できる
その他カスタマイズ
再起動時テーブル初期化指定
サービス起動時にDB保存したSession情報の取り扱いについて
「spring.session.jdbc.initialize-schema」で指定できる
常に初期化する:ALWAYS
Embedded Databaseのみ初期化する:EMBEDDED
なにもしない:NEVER
spring.session.jdbc.initialize-schema=NEVER
テーブル名カスタマイズ指定
「spring.session.jdbc.table-name」にカスタマイズしたテーブル名を記載
テーブル構成はデフォルト指定のテーブルと同一にする必要あり
spring.session.jdbc.table-name=SPRING_SESSION
クリーンアップタイミング指定
期限切れのセッションによるデータベースのオーバーロードを避けるために、Spring Session JDBC は期限切れのセッション (およびその属性) を削除するクリーンアップジョブを 1 分ごとに実行します。
下記アノテーションを設定することで、クリーンアップ間隔を指定できます
@EnableJdbcHttpSession(cleanupCron = "0 0 * * * *") // top of every hour of every da
参考資料
タイムスタンプ変換確認
Base64変換確認