前回 、Raspberry piで遊んだ時にTomcatによるSession Replicationを実装した。
今回はSpring BootとRedisでSession管理を外部化してSession Replicationを実装してみる。
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