Spring BootでSessionをRedisに保存する

前回、Raspberry piで遊んだ時にTomcatによるSession Replicationを実装した。

今回はSpring BootとRedisでSession管理を外部化してSession Replicationを実装してみる。

Redisのインストール

sudo apt install redis

Redisの設定

複数サーバーからアクセス出来るようにするため、アクセス制限を削除する。

sudo vi /etc/redis/redis.conf
下記の通り修正

bind 0.0.0.0 ::0 # 一時的に使用するだけなので全てのIPからアクセスOKにしている

Spring Bootでの実装例

build.gradleの依存関係部分
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-redis-reactive'
	implementation 'org.springframework.boot:spring-boot-starter-webflux'
	implementation 'org.springframework.session:spring-session-data-redis'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'io.projectreactor:reactor-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

Sessionオブジェクトの保存にRedisを使用するようにConfigを設定する。なお、外部にデータを保存することになるので、Sessionに入れるデータはSerializableである必要がある。

import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;

@Configuration
@EnableRedisWebSession()
public class SessionConfig {
}
Controllerの実装例
@RestController
@AllArgsConstructor
public class SessionController {

    @GetMapping("/websession")
    public Mono<SessionForm> getSession(WebSession session) {
        session.getAttributes().putIfAbsent("key", 0);
        session.getAttributes().putIfAbsent("note", "Nothing!");

        var sessionForm = new SessionForm();
        sessionForm.setKey((Integer) session.getAttributes().get("key"));
        sessionForm.setNote((String) session.getAttributes().get("note"));

        return Mono.just(sessionForm);
    }

    @GetMapping("/websession/test")
    public Mono<SessionForm> testWebSessionByParam(@RequestParam(value = "key") Integer key,
            @RequestParam(value = "note") String note, WebSession session) {
        session.getAttributes().put("key", key);
        session.getAttributes().put("note", note);

        var sessionForm = new SessionForm();
        sessionForm.setKey((Integer) session.getAttributes().get("key"));
        sessionForm.setNote((String) session.getAttributes().get("note"));

        return Mono.just(sessionForm);
    }
}

完全なコードはこちら。
https://github.com/hide6644/spring-session

動作確認

下記URLにアクセスするとパラメーターがSessionに保存される。
localhost:8080/websession/test?key=222&note=helloworld

下記のURLにアクセスすると、先ほど保存した文字が表示される。
localhost:8080/websession

{“key”:222,”note”:”helloworld”}

SessionをRedisに保存しているので、Spring Bootアプリをスケールアウトしても、それぞれのアプリでSessionが共有されていることが確認できると思う。

$ redis-cli
127.0.0.1:6379> keys *
1) "spring:session:sessions:セッションID"
127.0.0.1:6379> exit

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です