前回、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¬e=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