0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpringBootでSessionをDB管理で永続化する方法

Last updated at Posted at 2024-12-01

概要

SpringSessionをそのまま使用すると、デフォルトであるとサービスのメモリ内でセッション情報を管理しているため、複数サーバでロードバランスしている場合などセッション情報が複数台サーバにある場合、使い勝手が悪いという弱点があります。

上記弱点を補うため、セッション情報を外部で管理する方法があり、管理方法はいくつかありますが、今回はDB(Postgresq1)に保存する方法を例に紹介しようとおもいます。

SpringSession 設定

SpringSessionがあらかじめ反映されている状態からDB設定を実施する手順を示します。

依存関係の追加

SpringSessionでDB格納する依存関係を追加する

build.gradle
dependencies {
    implementation 'org.springframework.session:spring-session-jdbc'
}

SpringSession保存方式を指定

SpringSessionでSession情報をDB保存するよう「spring.session.store-type」に「jdbc」を指定

application.properties
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に反映する

session.ddl
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	
);

参照元
https://github.com/spring-projects/spring-session/tree/main/spring-session-jdbc/src/main/resources/org/springframework/session/jdbc

Java実装

Controllerクラスで、HttpSessionに対しSession情報を設定

ApiController.java

public class TestApiController {
	 
	@GetMapping
	public String getTest(HttpSession session) {
		
		session.setAttribute("sample", "sample");

		return "retValue";
	}

DB格納状態の確認

上記を実行しSession情報が格納されているかについて確認する

「SPRING_SESSION」テーブルを確認

image.png
Session登録時刻、最終更新時刻、Sessionタイムアウトまでの時刻、タイムアウトまでの時間が設定される

「SPRING_SESSION_ATTRIBUTES」テーブルを確認

image.png
HttpSettionで設定されたキーと値が設定される、値はバイナリ値で格納される

ブラウザ側のSession情報を確認

ブラウザ側にも同一セッション情報で渡ってきていることを確認

image.png
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変換確認

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?